diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py index 5f65697e901..febd47b98ea 100644 --- a/share/qtcreator/dumper/dumper.py +++ b/share/qtcreator/dumper/dumper.py @@ -841,6 +841,7 @@ qqEditable = {} qqStripForFormat = {} def stripForFormat(typeName): + global qqStripForFormat if typeName in qqStripForFormat: return qqStripForFormat[typeName] stripped = "" @@ -860,42 +861,31 @@ def stripForFormat(typeName): qqStripForFormat[typeName] = stripped return stripped -def bbsetup(args = ''): - typeCache = {} - module = sys.modules[__name__] - for key, value in module.__dict__.items(): - if key.startswith("qdump__"): - name = key[7:] - qqDumpers[name] = value - qqFormats[name] = qqFormats.get(name, "") - elif key.startswith("qform__"): - name = key[7:] + +def registerDumper(function): + global qqDumpers, qqFormats, qqEditable + try: + funcname = function.func_name + if funcname.startswith("qdump__"): + type = funcname[7:] + qqDumpers[type] = function + qqFormats[type] = qqFormats.get(type, "") + elif funcname.startswith("qform__"): + type = funcname[7:] formats = "" try: - formats = value() + formats = function() except: pass - qqFormats[name] = formats - elif key.startswith("qedit__"): - name = key[7:] + qqFormats[type] = formats + elif funcname.startswith("qedit__"): + type = funcname[7:] try: - qqEditable[name] = value + qqEditable[type] = function except: pass - result = "dumpers=[" - #qqNs = qtNamespace() # This is too early - for key, value in qqFormats.items(): - if qqEditable.has_key(key): - result += '{type="%s",formats="%s",editable="true"},' % (key, value) - else: - result += '{type="%s",formats="%s"},' % (key, value) - result += ']' - #result += ',namespace="%s"' % qqNs - result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList()) - return result - -registerCommand("bbsetup", bbsetup) - + except: + pass ####################################################################### # @@ -904,6 +894,7 @@ registerCommand("bbsetup", bbsetup) ####################################################################### def bbedit(args): + global qqEditable (type, expr, value) = args.split(",") type = base64.b16decode(type, True) ns = qtNamespace() @@ -1431,6 +1422,8 @@ class Dumper: self.putNumChild(0) return + global qqDumpers, qqFormats + type = value.type.unqualified() typeName = str(type) tryDynamic &= self.useDynamicType @@ -1666,8 +1659,8 @@ class Dumper: return # Fall back to plain pointer printing. - warn("GENERIC PLAIN POINTER: %s" % value.type) - warn("ADDR PLAIN POINTER: %s" % value.address) + #warn("GENERIC PLAIN POINTER: %s" % value.type) + #warn("ADDR PLAIN POINTER: %s" % value.address) self.putType(typeName) self.putField("aaa", "1") #self.put('addr="0x%x",' % long(value.address)) @@ -1733,6 +1726,7 @@ class Dumper: return #warn(" STRIPPED: %s" % nsStrippedType) + #warn(" DUMPERS: %s" % qqDumpers) #warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers)) dumper = qqDumpers.get(nsStrippedType, None) if not dumper is None: @@ -1942,44 +1936,6 @@ def threadnames(arg): registerCommand("threadnames", threadnames) -####################################################################### -# -# Import plain gdb pretty printers -# -####################################################################### - -class PlainDumper: - def __init__(self, printer): - self.printer = printer - - def __call__(self, d, value): - printer = self.printer.gen_printer(value) - lister = getattr(printer, "children", None) - children = [] if lister is None else list(lister()) - d.putType(self.printer.name) - val = printer.to_string().encode("hex") - d.putValue(val, Hex2EncodedLatin1) - d.putValue(printer.to_string()) - d.putNumChild(len(children)) - if d.isExpanded(): - with Children(d): - for child in children: - d.putSubItem(child[0], child[1]) - -def importPlainDumper(printer): - name = printer.name.replace("::", "__") - qqDumpers[name] = PlainDumper(printer) - qqFormats[name] = "" - -def importPlainDumpers(args): - for obj in gdb.objfiles(): - for printers in obj.pretty_printers + gdb.pretty_printers: - for printer in printers.subprinters: - importPlainDumper(printer) - -registerCommand("importPlainDumpers", importPlainDumpers) - - ####################################################################### # # Mixed C++/Qml debugging diff --git a/share/qtcreator/dumper/gbridge.py b/share/qtcreator/dumper/gbridge.py index 6903a38c506..4eec5f92643 100644 --- a/share/qtcreator/dumper/gbridge.py +++ b/share/qtcreator/dumper/gbridge.py @@ -1,9 +1,10 @@ import binascii +import gdb import inspect import os +import sys import traceback -import gdb cdbLoaded = False lldbLoaded = False @@ -333,8 +334,72 @@ class ScanStackCommand(gdb.Command): ScanStackCommand() +def bbsetup(args = ''): + global qqDumpers, qqFormats, qqEditable, typeCache + typeCache = {} + module = sys.modules[__name__] + + for key, value in module.__dict__.items(): + registerDumper(value) + + result = "dumpers=[" + #qqNs = qtNamespace() # This is too early + for key, value in qqFormats.items(): + if qqEditable.has_key(key): + result += '{type="%s",formats="%s",editable="true"},' % (key, value) + else: + result += '{type="%s",formats="%s"},' % (key, value) + result += ']' + #result += ',namespace="%s"' % qqNs + result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList()) + return result + +registerCommand("bbsetup", bbsetup) + + +####################################################################### +# +# Import plain gdb pretty printers +# +####################################################################### + +class PlainDumper: + def __init__(self, printer): + self.printer = printer + + def __call__(self, d, value): + printer = self.printer.gen_printer(value) + lister = getattr(printer, "children", None) + children = [] if lister is None else list(lister()) + d.putType(self.printer.name) + val = printer.to_string().encode("hex") + d.putValue(val, Hex2EncodedLatin1) + d.putValue(printer.to_string()) + d.putNumChild(len(children)) + if d.isExpanded(): + with Children(d): + for child in children: + d.putSubItem(child[0], child[1]) + +def importPlainDumper(printer): + global qqDumpers, qqFormats + name = printer.name.replace("::", "__") + qqDumpers[name] = PlainDumper(printer) + qqFormats[name] = "" + +def importPlainDumpers(args): + return + for obj in gdb.objfiles(): + for printers in obj.pretty_printers + gdb.pretty_printers: + for printer in printers.subprinters: + importPlainDumper(printer) + +registerCommand("importPlainDumpers", importPlainDumpers) + + gdbLoaded = True currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) execfile(os.path.join(currentDir, "dumper.py")) execfile(os.path.join(currentDir, "qttypes.py")) + bbsetup() diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 1f81ca6af9e..be3cdc68261 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -49,10 +49,9 @@ SimpleValueCode = None # LLDB only #warn("LOADING LLDB") # Data members -SimpleValueCode, \ -StructCode, \ -PointerCode \ - = range(3) +SimpleValueCode = 100 +StructCode = 101 +PointerCode = 102 # Breakpoints. Keep synchronized with BreakpointType in breakpoint.h UnknownType = 0 @@ -95,6 +94,9 @@ class Type: def unqualified(self): return self + def strip_typedefs(self): + return self + class Value: def __init__(self, var): self.raw = var @@ -106,6 +108,9 @@ class Value: def __str__(self): return str(self.raw.value) + def __getitem__(self, name): + return None if self.raw is None else self.raw.GetChildMemberWithName(name) + def fields(self): return [Value(self.raw.GetChildAtIndex(i)) for i in range(self.raw.num_children)] @@ -397,10 +402,22 @@ lldb.debugger.HandleCommand("settings set interpreter.prompt-on-quit off") lldb.debugger.HandleCommand("settings set frame-format ''") lldb.debugger.HandleCommand("settings set thread-format ''") -lldbLoaded = True - execfile(os.path.join(currentDir, "dumper.py")) execfile(os.path.join(currentDir, "qttypes.py")) + +def importPlainDumpers(args): + pass + +def bbsetup(args = ''): + global qqDumpers, qqFormats, qqEditable + typeCache = {} + + items = globals() + for key in items: + registerDumper(items[key]) + bbsetup() -print "result={state=\"enginesetupok\"}" +lldbLoaded = True + +print "result={state=\"enginesetupok\",dumpers=\"%s\"}" % qqDumpers.keys() diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index a11fb59373e..bb59cab95d8 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -1033,7 +1033,37 @@ void LldbEngine::refreshLocation(const GdbMi &reportedLocation) bool LldbEngine::hasCapability(unsigned cap) const { - return cap & (ReloadModuleCapability|BreakConditionCapability); + if (cap & (ReverseSteppingCapability + | AutoDerefPointersCapability + | DisassemblerCapability + | RegisterCapability + | ShowMemoryCapability + | JumpToLineCapability + | ReloadModuleCapability + | ReloadModuleSymbolsCapability + | BreakOnThrowAndCatchCapability + | BreakConditionCapability + | TracePointCapability + | ReturnFromFunctionCapability + | CreateFullBacktraceCapability + | WatchpointByAddressCapability + | WatchpointByExpressionCapability + | AddWatcherCapability + | WatchWidgetsCapability + | ShowModuleSymbolsCapability + | ShowModuleSectionsCapability + | CatchCapability + | OperateByInstructionCapability + | RunToLineCapability + | WatchComplexExpressionsCapability + | MemoryAddressCapability)) + return true; + + if (startParameters().startMode == AttachCore) + return false; + + //return cap == SnapshotCapability; + return false; } DebuggerEngine *createLldbEngine(const DebuggerStartParameters &startParameters)