diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 42cf770c0ffc3f34a07bcac9a62c4eaf11566323..16dc5d2d52c10599274865448e1eb4fc19117e10 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -34,6 +34,8 @@ import sys import base64 import re import time +import importlib + try: import subprocess hasSubprocess = True @@ -1635,6 +1637,65 @@ class DumperBase: self.currentNumChild = 0 self.putNumChild(0) + def registerDumper(self, funcname, function): + try: + #warn("FUNCTION: %s " % funcname) + #funcname = function.func_name + if funcname.startswith("qdump__"): + typename = funcname[7:] + self.qqDumpers[typename] = function + self.qqFormats[typename] = self.qqFormats.get(typename, "") + elif funcname.startswith("qform__"): + typename = funcname[7:] + formats = "" + try: + formats = function() + except: + pass + self.qqFormats[typename] = formats + elif funcname.startswith("qedit__"): + typename = funcname[7:] + try: + self.qqEditable[typename] = function + except: + pass + except: + pass + + def findDumperFunctions(self): + self.qqDumpers = {} + self.qqFormats = {} + self.qqEditable = {} + self.typeCache = {} + + for mod in dumpermodules: + m = importlib.import_module(mod) + dic = m.__dict__ + for name in dic.keys(): + item = dic[name] + self.registerDumper(name, item) + + return self.reportDumpers() + + def reportDumpers(self): + result = "dumpers=[" + for key, value in self.qqFormats.items(): + if key in self.qqEditable: + result += '{type="%s",formats="%s",editable="true"},' % (key, value) + else: + result += '{type="%s",formats="%s"},' % (key, value) + result += ']' + return result + + def reloadDumper(self): + for mod in dumpermodules: + m = sys.modules[mod] + if sys.version_info[0] >= 3: + importlib.reload(m) + else: + reload(m) + + findDumperFunctions() # Some "Enums" @@ -1681,3 +1742,12 @@ DisplayUtf8String \ = range(6) +dumpermodules = [ + "qttypes", + "stdtypes", + "misctypes", + "boosttypes", + "creatortypes", + "personaltypes", +] + diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 6dd2157c43b5bf471ca94886530f3caa20325d20..061ff9a239bb9567a4801641608198fb83b52445 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -14,25 +14,11 @@ import sys import struct import types -import importlib - def warn(message): print("XXX: %s\n" % message.encode("latin1")) from dumper import * -dumpermodules = [ - "qttypes", - "stdtypes", - "misctypes", - "boosttypes", - "creatortypes", - "personaltypes", -] - -for mod in dumpermodules: - importlib.import_module(mod) - ####################################################################### # @@ -150,8 +136,7 @@ ScanStackCommand() def bbsetup(args = ''): - theDumper.bbsetup() - print(theDumper.reportDumpers()) + print(theDumper.findDumperFunctions()) registerCommand("bbsetup", bbsetup) @@ -1423,55 +1408,6 @@ class Dumper(DumperBase): with Children(self, 1): self.listAnonymous(value, name, field.type) - def registerDumper(self, funcname, function): - try: - #warn("FUNCTION: %s " % funcname) - #funcname = function.func_name - if funcname.startswith("qdump__"): - typename = funcname[7:] - self.qqDumpers[typename] = function - self.qqFormats[typename] = self.qqFormats.get(typename, "") - elif funcname.startswith("qform__"): - typename = funcname[7:] - formats = "" - try: - formats = function() - except: - pass - self.qqFormats[typename] = formats - elif funcname.startswith("qedit__"): - typename = funcname[7:] - try: - self.qqEditable[typename] = function - except: - pass - except: - pass - - def bbsetup(self): - self.qqDumpers = {} - self.qqFormats = {} - self.qqEditable = {} - self.typeCache = {} - - for mod in dumpermodules: - m = importlib.import_module(mod) - dic = m.__dict__ - for name in dic.keys(): - item = dic[name] - self.registerDumper(name, item) - - - def reportDumpers(self): - result = "dumpers=[" - for key, value in self.qqFormats.items(): - if key in self.qqEditable: - result += '{type="%s",formats="%s",editable="true"},' % (key, value) - else: - result += '{type="%s",formats="%s"},' % (key, value) - result += ']' - return result - #def threadname(self, maximalStackDepth, objectPrivateType): # e = gdb.selected_frame() # out = "" @@ -2044,15 +1980,8 @@ registerCommand("threadnames", threadnames) # ####################################################################### -def reloadDumper(arg): - for mod in dumpermodules: - m = sys.modules[mod] - if sys.version_info[0] >= 3: - importlib.reload(m) - else: - reload(m) - - bbsetup() +def reloadDumper(_): + theDumper.reloadDumper(); registerCommand("reload", reloadDumper) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7d3e4dc180ab1c2efc8080e994fbf06acb598878..630e1fe00f01472dac5044364baf6c64df7bb3e1 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -672,7 +672,6 @@ class Dumper(DumperBase): self.target = self.debugger.CreateTarget(self.executable_, None, None, True, error) else: self.target = self.debugger.CreateTarget(None, None, None, True, error) - self.importDumpers() state = "inferiorsetupok" if self.target.IsValid() else "inferiorsetupfailed" self.report('state="%s",msg="%s",exe="%s"' % (state, error, self.executable_)) @@ -1583,7 +1582,7 @@ class Dumper(DumperBase): path = args['path'] (head, tail) = os.path.split(path) sys.path.insert(1, head) - #dumpermodules.append(os.path.splitext(tail)[0]) + dumpermodules.append(os.path.splitext(tail)[0]) self.report('ok') def updateData(self, args): @@ -1642,6 +1641,10 @@ class Dumper(DumperBase): result += ',offset="%s"},' % (addr - base) self.report(result + ']') + def loadDumperFiles(self, _ = None): + result = self.findDumperFunctions() + self.report(result) + def fetchMemory(self, args): address = args['address'] length = args['length'] @@ -1668,35 +1671,6 @@ class Dumper(DumperBase): self.reportError(error) self.reportVariables() - def registerDumper(self, function): - if hasattr(function, 'func_name'): - funcname = function.func_name - if funcname.startswith("qdump__"): - type = funcname[7:] - self.qqDumpers[type] = function - self.qqFormats[type] = self.qqFormats.get(type, "") - elif funcname.startswith("qform__"): - type = funcname[7:] - formats = "" - try: - formats = function() - except: - pass - self.qqFormats[type] = formats - elif funcname.startswith("qedit__"): - type = funcname[7:] - try: - self.qqEditable[type] = function - except: - pass - - def importDumpers(self, _ = None): - result = lldb.SBCommandReturnObject() - interpreter = self.debugger.GetCommandInterpreter() - items = globals() - for key in items: - self.registerDumper(items[key]) - def execute(self, args): getattr(self, args['cmd'])(args) self.report('token="%s"' % args['token']) @@ -1754,7 +1728,7 @@ class Tester(Dumper): self.expandedINames = set(sys.argv[3].split(',')) self.passExceptions = True - self.importDumpers() + self.loadDumperFiles() error = lldb.SBError() self.target = self.debugger.CreateTarget(sys.argv[2], None, None, True, error) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index a828b37cb7cf1e9bbbe530cba01b847ae45f52a0..0c541070500751b1def56fe97ba47c2e65d9ba95 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1737,22 +1737,7 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response) if (response.resultClass == GdbResultDone) { GdbMi data; data.fromStringMultiple(response.consoleStreamOutput); - const GdbMi dumpers = data["dumpers"]; - foreach (const GdbMi &dumper, dumpers.children()) { - QByteArray type = dumper["type"].data(); - QStringList formats(tr("Raw structure")); - foreach (const QByteArray &format, - dumper["formats"].data().split(',')) { - if (format == "Normal") - formats.append(tr("Normal")); - else if (format == "Displayed") - formats.append(tr("Displayed")); - else if (!format.isEmpty()) - formats.append(_(format)); - } - watchHandler()->addTypeFormats(type, formats); - } - + watchHandler()->addDumpers(data["dumpers"]); loadInitScript(); QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("ENGINE SUCCESSFULLY STARTED")); diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 82a9ef9bb74e96665af7bb1fac0c35b34f6c5783..16d2190ecf1148784102b3606deb6443853497b0 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -281,10 +281,13 @@ void LldbEngine::setupInferior() const QString commands = stringSetting(ExtraDumperCommands); if (!commands.isEmpty()) { Command cmd("executeDebuggerCommand"); - cmd.arg(commands.toUtf8()); + cmd.arg("commands", commands.toUtf8()); runCommand(cmd); } + Command cmd1("loadDumperFiles"); + runCommand(cmd1); + QString executable; QtcProcess::Arguments args; QtcProcess::prepareCommand(QFileInfo(sp.executable).absoluteFilePath(), @@ -409,6 +412,8 @@ void LldbEngine::handleResponse(const QByteArray &response) const QByteArray name = item.name(); if (name == "data") refreshLocals(item); + else if (name == "dumpers") + watchHandler()->addDumpers(item); else if (name == "stack") refreshStack(item); else if (name == "stack-position") diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 1bbc6d45e4ba5d30c728ca301cb653c883f0581f..eeb0d4664c990af5eb88f73e60ce672200757dd9 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1783,6 +1783,22 @@ QByteArray WatchHandler::individualFormatRequests() const return ba; } +void WatchHandler::addDumpers(const GdbMi &dumpers) +{ + foreach (const GdbMi &dumper, dumpers.children()) { + QStringList formats(tr("Raw structure")); + foreach (const QByteArray &format, dumper["formats"].data().split(',')) { + if (format == "Normal") + formats.append(tr("Normal")); + else if (format == "Displayed") + formats.append(tr("Displayed")); + else if (!format.isEmpty()) + formats.append(QString::fromLatin1(format)); + } + addTypeFormats(dumper["type"].data(), formats); + } +} + void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats) { m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 46f326aaf9ea8e33a93c873cb88147d46ff0b36e..5a30e0a778b5c1180ded6c844cdda8cc426870e9 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -217,6 +217,7 @@ public: int format(const QByteArray &iname) const; + void addDumpers(const GdbMi &dumpers); void addTypeFormats(const QByteArray &type, const QStringList &formats); void setTypeFormats(const DumperTypeFormats &typeFormats); DumperTypeFormats typeFormats() const;