From 70fc039796187be36af5949ab77d394961c4e4da Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 4 Apr 2013 16:43:25 +0200 Subject: [PATCH] Debugger: Show simple values with LLDB backend Change-Id: Iccef8c0ddb1951da1b09b13b1ce2a0cee716c30f Reviewed-by: hjk --- share/qtcreator/dumper/bridge.py | 120 ++++++++++++++++------- share/qtcreator/dumper/dumper.py | 5 +- src/plugins/debugger/lldb/lldbengine.cpp | 40 ++++---- 3 files changed, 106 insertions(+), 59 deletions(-) diff --git a/share/qtcreator/dumper/bridge.py b/share/qtcreator/dumper/bridge.py index 948404faeae..c80ae5a8160 100644 --- a/share/qtcreator/dumper/bridge.py +++ b/share/qtcreator/dumper/bridge.py @@ -11,10 +11,6 @@ gdbLoaded = False # ####################################################################### -def warn(message): - print "XXX: %s\n" % message.encode("latin1") - - def showException(msg, exType, exValue, exTraceback): warn("**** CAUGHT EXCEPTION: %s ****" % msg) try: @@ -24,6 +20,33 @@ def showException(msg, exType, exValue, exTraceback): except: pass +PointerCode = None +ArrayCode = None +StructCode = None +UnionCode = None +EnumCode = None +FlagsCode = None +FunctionCode = None +IntCode = None +FloatCode = None +VoidCode = None +SetCode = None +RangeCode = None +StringCode = None +BitStringCode = None +ErrorTypeCode = None +MethodCode = None +MethodPointerCode = None +MemberPointerCode = None +ReferenceCode = None +CharCode = None +BoolCode = None +ComplexCode = None +TypedefCode = None +NamespaceCode = None +SimpleValueCode = None # LLDB only + + ####################################################################### # @@ -36,6 +59,7 @@ try: cdbLoaded = True except: + #warn("LOADING CDB FAILED") pass @@ -52,6 +76,11 @@ try: import gdb gdbLoaded = True + def warn(message): + print "XXX: %s\n" % message.encode("latin1") + + #warn("LOADING GDB") + ####################################################################### # # Infrastructure @@ -329,6 +358,30 @@ try: base += 1 return s + def extractFields(type): + return type.fields() + ## Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953: + ##fields = type.fields() + ## Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777: + ##fields = defsype).fields() + ## This seems to work. + ##warn("TYPE 0: %s" % type) + #type = stripTypedefs(type) + #fields = type.fields() + #if len(fields): + # return fields + ##warn("TYPE 1: %s" % type) + ## This fails for arrays. See comment in lookupType. + #type0 = lookupType(str(type)) + #if not type0 is None: + # type = type0 + #if type.code == FunctionCode: + # return [] + ##warn("TYPE 2: %s" % type) + #fields = type.fields() + ##warn("FIELDS: %s" % fields) + #return fields + ####################################################################### # # Types @@ -435,6 +488,7 @@ try: except: + #warn("LOADING GDB FAILED") pass @@ -450,43 +504,33 @@ try: lldbLoaded = True - PointerCode, \ - ArrayCode, \ + def warn(message): + print "XXX: %s\n" % message.encode("latin1") + + #warn("LOADING LLDB") + + SimpleValueCode, \ StructCode, \ - UnionCode, \ - EnumCode, \ - FlagsCode, \ - FunctionCode, \ - IntCode, \ - FloatCode, \ - VoidCode, \ - SetCode, \ - RangeCode, \ - StringCode, \ - BitStringCode, \ - ErrorTypeCode, \ - MethodCode, \ - MethodPointerCode, \ - MemberPointerCode, \ - ReferenceCode, \ - CharCode, \ - BoolCode, \ - ComplexCode, \ - TypedefCode, \ - NamespaceCode \ - = range(24) + PointerCode \ + = range(3) def registerCommand(name, func): pass class Type: - def __init__(self, type): - self.raw = type - self.code = IntCode + def __init__(self, var): + self.raw = var + if var.num_children == 0: + self.code = SimpleValueCode + else: + self.code = StructCode + self.value_type = var.value_type def __str__(self): - return self.raw.name - + #try: + return self.raw.type.name + #except: + # return "" def unqualified(self): return self @@ -495,11 +539,11 @@ try: def __init__(self, var): self.raw = var self.is_optimized_out = False - self.type = Type(var.type) - self.type.value_type = var.value_type + self.address = var.addr + self.type = Type(var) def __str__(self): - return self.name + return str(self.raw.value) currentThread = None currentFrame = None @@ -519,7 +563,11 @@ try: items.append(item) return items + def extractFields(type): + return type.fields() + except: + #warn("LOADING LLDB FAILED") pass diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py index 0d6cbcceedb..774650a09b6 100644 --- a/share/qtcreator/dumper/dumper.py +++ b/share/qtcreator/dumper/dumper.py @@ -512,7 +512,8 @@ def isSimpleType(typeobj): or code == CharCode \ or code == IntCode \ or code == FloatCode \ - or code == EnumCode + or code == EnumCode \ + or code == SimpleValueCode def simpleEncoding(typeobj): code = typeobj.code @@ -1494,7 +1495,7 @@ class Dumper: self.putNumChild(0) return - if type.code == IntCode or type.code == CharCode: + if type.code == IntCode or type.code == CharCode or type.code == SimpleValueCode: self.putType(typeName) if value.is_optimized_out: self.putValue("") diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 04e657ca645..24eb084d4e3 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -853,35 +853,33 @@ void LldbEngine::handleBacktrace(const LldbResponse &response) void LldbEngine::handleListLocals(const LldbResponse &response) { //qDebug() << " LOCALS: '" << response.data << "'"; - QByteArray out = response.data.trimmed(); + QByteArray out = response.data; -// GdbMi all; -// all.fromStringMultiple(out); -// //qDebug() << "ALL: " << all.toString(); + { + int pos = out.indexOf("data="); + if (pos == -1) { + showMessage(_("UNEXPECTED LOCALS OUTPUT:" + out)); + return; + } -// //GdbMi data = all.findChild("data"); -// QList list; -// WatchHandler *handler = watchHandler(); -// foreach (const GdbMi &child, all.children()) { -// WatchData dummy; -// dummy.iname = child.findChild("iname").data(); -// dummy.name = _(child.findChild("name").data()); -// //qDebug() << "CHILD: " << child.toString(); -// parseWatchData(handler->expandedINames(), dummy, child, &list); -// } -// handler->insertData(list); - - const bool partial = response.cookie.toBool(); - int pos = out.indexOf("data="); - if (pos != 0) { - showMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: " - + out.left(pos))); + // The value in 'out' should be single-quoted as this is + // what the command line does with strings. + if (pos != 1) { + showMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: " + + out.left(pos))); + } out = out.mid(pos); + if (out.endsWith('\'')) + out.chop(1); + else + showMessage(_("JUNK AT END OF RESPONSE: " + out)); } + GdbMi all; all.fromStringMultiple(out); GdbMi data = all.findChild("data"); + const bool partial = response.cookie.toBool(); WatchHandler *handler = watchHandler(); QList list;