From 3cee7dad0a90ff461a86b033c2f87a8f9ff28d7d Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Fri, 23 Jul 2010 16:05:56 +0200 Subject: [PATCH] debugger: make parts of python debugger work again with the new states --- share/qtcreator/gdbmacros/pdumper.py | 465 ++++++++++--------- src/plugins/debugger/pdb/pdbengine.cpp | 173 ++++--- src/plugins/debugger/pdb/pdbengine.h | 9 +- src/plugins/debugger/script/scriptengine.cpp | 7 +- tests/manual/gdbdebugger/python/math.py | 4 +- 5 files changed, 357 insertions(+), 301 deletions(-) diff --git a/share/qtcreator/gdbmacros/pdumper.py b/share/qtcreator/gdbmacros/pdumper.py index 874597b3e3d..e0144490abb 100644 --- a/share/qtcreator/gdbmacros/pdumper.py +++ b/share/qtcreator/gdbmacros/pdumper.py @@ -3,239 +3,250 @@ import pdb; import sys; import linecache - -class qdebug: - def __init__(self, - options = None, +def qdebug(options = None, expanded = None, typeformats = None, individualformats = None, watchers = None): - self.options = options - self.expandedINames = expanded - self.typeformats = typeformats - self.individualformats = individualformats - self.watchers = watchers - if self.options == "listmodules": - self.handleListModules() - elif self.options == "listsymbols": - self.handleListSymbols(expanded) - else: - self.handleListVars() - - def put(self, value): - sys.stdout.write(value) - - def putField(self, name, value): - self.put('%s="%s",' % (name, value)) - - def putItemCount(self, count): - self.put('value="<%s items>",' % count) - - def putEllipsis(self): - self.put('{name="<incomplete>",value="",type="",numchild="0"},') - - def cleanType(self, type): - t = str(type) - if t.startswith("<type '") and t.endswith("'>"): - t = t[7:-2] - if t.startswith("<class '") and t.endswith("'>"): - t = t[8:-2] - return t - - def putType(self, type, priority = 0): - self.putField("type", self.cleanType(type)) - - def putAddress(self, addr): - self.put('addr="%s",' % cleanAddress(addr)) - - def putNumChild(self, numchild): - self.put('numchild="%s",' % numchild) - - def putValue(self, value, encoding = None, priority = 0): - self.putField("value", value) - - def putName(self, name): - self.put('name="%s",' % name) - - def isExpanded(self, iname): - #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames)) - if iname.startswith("None"): - raise "Illegal iname '%s'" % iname - #self.warn(" --> %s" % (iname in self.expandedINames)) - return iname in self.expandedINames - - def isExpandedIName(self, iname): - return iname in self.expandedINames - - def itemFormat(self, item): - format = self.formats.get(str(cleanAddress(item.value.address))) - if format is None: - format = self.typeformats.get(stripClassTag(str(item.value.type))) - return format - - def dumpFrame(self, frame): - for var in frame.f_locals.keys(): - if var == "__file__": - continue - #if var == "__name__": - # continue - if var == "__package__": - continue - if var == "qdebug": - continue - if var != '__builtins__': - value = frame.f_locals[var] - self.dumpValue(value, var, "local.%s" % var) - - def dumpValue(self, value, name, iname): - t = type(value) - tt = self.cleanType(t) - if tt == "module" or tt == "function": - return - if str(value).startswith("<class '"): - return - # FIXME: Should we? - if str(value).startswith("<enum-item "): - return - self.put("{") - self.putField("iname", iname) - self.putName(name) - self.putType(tt) - if tt == "NoneType": - self.putValue("None") - self.putNumChild(0) - elif tt == "list" or tt == "tuple": - self.putItemCount(len(value)) - #self.putValue(value) - self.put("children=[") - for i in xrange(len(value)): - self.dumpValue(value[i], str(i), "%s.%d" % (iname, i)) - self.put("]") - elif tt == "str": - v = value - self.putValue(v.encode('hex')) - self.putField("valueencoded", 6) - self.putNumChild(0) - elif tt == "unicode": - v = value - self.putValue(v.encode('hex')) - self.putField("valueencoded", 6) - self.putNumChild(0) - elif tt == "buffer": - v = str(value) - self.putValue(v.encode('hex')) - self.putField("valueencoded", 6) - self.putNumChild(0) - elif tt == "xrange": - b = iter(value).next() - e = b + len(value) - self.putValue("(%d, %d)" % (b, e)) - self.putNumChild(0) - elif tt == "dict": - self.putItemCount(len(value)) - self.putField("childnumchild", 2) - self.put("children=[") - i = 0 - for (k, v) in value.iteritems(): - self.put("{") - self.putType(" ") - self.putValue("%s: %s" % (k, v)) + + class QDebug: + def __init__(self, + options = None, + expanded = None, + typeformats = None, + individualformats = None, + watchers = None): + self.options = options + self.expandedINames = expanded + self.typeformats = typeformats + self.individualformats = individualformats + self.watchers = watchers + self.buffer = "" + if self.options == "listmodules": + self.handleListModules() + elif self.options == "listsymbols": + self.handleListSymbols(expanded) + else: + self.handleListVars() + + def put(self, value): + #sys.stdout.write(value) + self.buffer += value + + def putField(self, name, value): + self.put('%s="%s",' % (name, value)) + + def putItemCount(self, count): + self.put('value="<%s items>",' % count) + + def putEllipsis(self): + self.put('{name="<incomplete>",value="",type="",numchild="0"},') + + def cleanType(self, type): + t = str(type) + if t.startswith("<type '") and t.endswith("'>"): + t = t[7:-2] + if t.startswith("<class '") and t.endswith("'>"): + t = t[8:-2] + return t + + def putType(self, type, priority = 0): + self.putField("type", self.cleanType(type)) + + def putAddress(self, addr): + self.put('addr="%s",' % cleanAddress(addr)) + + def putNumChild(self, numchild): + self.put('numchild="%s",' % numchild) + + def putValue(self, value, encoding = None, priority = 0): + self.putField("value", value) + + def putName(self, name): + self.put('name="%s",' % name) + + def isExpanded(self, iname): + #self.warn("IS EXPANDED: %s in %s" % (iname, self.expandedINames)) + if iname.startswith("None"): + raise "Illegal iname '%s'" % iname + #self.warn(" --> %s" % (iname in self.expandedINames)) + return iname in self.expandedINames + + def isExpandedIName(self, iname): + return iname in self.expandedINames + + def itemFormat(self, item): + format = self.formats.get(str(cleanAddress(item.value.address))) + if format is None: + format = self.typeformats.get(stripClassTag(str(item.value.type))) + return format + + def dumpFrame(self, frame): + for var in frame.f_locals.keys(): + if var == "__file__": + continue + #if var == "__name__": + # continue + if var == "__package__": + continue + if var == "qdebug": + continue + if var != '__builtins__': + value = frame.f_locals[var] + self.dumpValue(value, var, "local.%s" % var) + + def dumpValue(self, value, name, iname): + t = type(value) + tt = self.cleanType(t) + if tt == "module" or tt == "function": + return + if str(value).startswith("<class '"): + return + # FIXME: Should we? + if str(value).startswith("<enum-item "): + return + self.put("{") + self.putField("iname", iname) + self.putName(name) + self.putType(tt) + if tt == "NoneType": + self.putValue("None") + self.putNumChild(0) + elif tt == "list" or tt == "tuple": + self.putItemCount(len(value)) + #self.putValue(value) + self.put("children=[") + for i in xrange(len(value)): + self.dumpValue(value[i], str(i), "%s.%d" % (iname, i)) + self.put("]") + elif tt == "str": + v = value + self.putValue(v.encode('hex')) + self.putField("valueencoded", 6) + self.putNumChild(0) + elif tt == "unicode": + v = value + self.putValue(v.encode('hex')) + self.putField("valueencoded", 6) + self.putNumChild(0) + elif tt == "buffer": + v = str(value) + self.putValue(v.encode('hex')) + self.putField("valueencoded", 6) + self.putNumChild(0) + elif tt == "xrange": + b = iter(value).next() + e = b + len(value) + self.putValue("(%d, %d)" % (b, e)) + self.putNumChild(0) + elif tt == "dict": + self.putItemCount(len(value)) + self.putField("childnumchild", 2) + self.put("children=[") + i = 0 + for (k, v) in value.iteritems(): + self.put("{") + self.putType(" ") + self.putValue("%s: %s" % (k, v)) + if self.isExpanded(iname): + self.put("children=[") + self.dumpValue(k, "key", "%s.%d.k" % (iname, i)) + self.dumpValue(v, "value", "%s.%d.v" % (iname, i)) + self.put("]") + self.put("},") + i += 1 + self.put("]") + elif tt == "class": + pass + elif tt == "module": + pass + elif tt == "function": + pass + elif str(value).startswith("<enum-item "): + # FIXME: Having enums always shown like this is not nice. + self.putValue(str(value)[11:-1]) + self.putNumChild(0) + else: + v = str(value) + p = v.find(" object at ") + if p > 1: + v = "@" + v[p + 11:-1] + self.putValue(v) if self.isExpanded(iname): self.put("children=[") - self.dumpValue(k, "key", "%s.%d.k" % (iname, i)) - self.dumpValue(v, "value", "%s.%d.v" % (iname, i)) - self.put("]") + for child in dir(value): + if child == "__dict__": + continue + if child == "__doc__": + continue + if child == "__module__": + continue + attr = getattr(value, child) + if callable(attr): + continue + try: + self.dumpValue(attr, child, "%s.%s" % (iname, child)) + except: + pass + self.put("],") + self.put("},") + + + def warn(self, msg): + self.putField("warning", msg) + + def handleListVars(self): + # Trigger error to get a backtrace. + frame = None + #self.warn("frame: %s" % frame) + try: + raise ZeroDivisionError + except ZeroDivisionError: + frame = sys.exc_info()[2].tb_frame.f_back + + limit = 30 + n = 0 + isActive = False + while frame is not None and n < limit: + #self.warn("frame: %s" % frame.f_locals.keys()) + lineno = frame.f_lineno + code = frame.f_code + filename = code.co_filename + name = code.co_name + if isActive: + linecache.checkcache(filename) + line = linecache.getline(filename, lineno, frame.f_globals) + self.dumpFrame(frame) + if name == "<module>": + isActive = False + if name == "trace_dispatch": + isActive = True + frame = frame.f_back + n = n + 1 + #sys.stdout.flush() + + def handleListModules(self): + self.put("modules=["); + for name in sys.modules: + self.put("{") + self.putName(name) + self.putValue(sys.modules[name]) self.put("},") - i += 1 self.put("]") - elif tt == "class": - pass - elif tt == "module": - pass - elif tt == "function": - pass - elif str(value).startswith("<enum-item "): - # FIXME: Having enums always shown like this is not nice. - self.putValue(str(value)[11:-1]) - self.putNumChild(0) - else: - v = str(value) - p = v.find(" object at ") - if p > 1: - v = "@" + v[p + 11:-1] - self.putValue(v) - if self.isExpanded(iname): - self.put("children=[") - for child in dir(value): - if child == "__dict__": - continue - if child == "__doc__": - continue - if child == "__module__": - continue - attr = getattr(value, child) - if callable(attr): - continue - try: - self.dumpValue(attr, child, "%s.%s" % (iname, child)) - except: - pass - self.put("],") - self.put("},") - - - def warn(self, msg): - self.putField("warning", msg) - - def handleListVars(self): - # Trigger error to get a backtrace. - frame = None - #self.warn("frame: %s" % frame) - try: - raise ZeroDivisionError - except ZeroDivisionError: - frame = sys.exc_info()[2].tb_frame.f_back - - limit = 30 - n = 0 - isActive = False - while frame is not None and n < limit: - #self.warn("frame: %s" % frame.f_locals.keys()) - lineno = frame.f_lineno - code = frame.f_code - filename = code.co_filename - name = code.co_name - if isActive: - linecache.checkcache(filename) - line = linecache.getline(filename, lineno, frame.f_globals) - self.dumpFrame(frame) - if name == "<module>": - isActive = False - if name == "trace_dispatch": - isActive = True - frame = frame.f_back - n = n + 1 - - sys.stdout.flush() - - def handleListModules(self): - self.put("modules=["); - for name in sys.modules: - self.put("{") - self.putName(name) - self.putValue(sys.modules[name]) - self.put("},") - self.put("]") - sys.stdout.flush() + #sys.stdout.flush() - def handleListSymbols(self, module): - #self.put("symbols=%s" % dir(sys.modules[module])) - self.put("symbols=["); - for name in sys.modules: - self.put("{") - self.putName(name) - #self.putValue(sys.modules[name]) - self.put("},") - self.put("]") - sys.stdout.flush() + def handleListSymbols(self, module): + #self.put("symbols=%s" % dir(sys.modules[module])) + self.put("symbols=["); + for name in sys.modules: + self.put("{") + self.putName(name) + #self.putValue(sys.modules[name]) + self.put("},") + self.put("]") + #sys.stdout.flush() + + d = QDebug(options, expanded, typeformats, individualformats, watchers) + #print d.buffer + sys.stdout.write(d.buffer) + sys.stdout.flush() diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 0863a9f0742..abd63b0e7d1 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -61,8 +61,8 @@ #include <QtCore/QVariant> #include <QtGui/QApplication> -#include <QtGui/QToolTip> #include <QtGui/QMessageBox> +#include <QtGui/QToolTip> #define DEBUG_SCRIPT 1 @@ -94,12 +94,26 @@ PdbEngine::~PdbEngine() void PdbEngine::executeDebuggerCommand(const QString &command) { - XSDEBUG("PdbEngine::executeDebuggerCommand:" << command); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + //XSDEBUG("PdbEngine::executeDebuggerCommand:" << command); if (state() == DebuggerNotReady) { showMessage(_("PDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command); return; } - m_pdbProc.write(command.toLatin1() + "\n"); + QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll()); + postCommand(command.toLatin1(), CB(handleExecuteDebuggerCommand)); +} + +void PdbEngine::handleExecuteDebuggerCommand(const PdbResponse &response) +{ + Q_UNUSED(response); +} + +void PdbEngine::postDirectCommand(const QByteArray &command) +{ + QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll()); + showMessage(_(command), LogInput); + m_pdbProc.write(command + "\n"); } void PdbEngine::postCommand(const QByteArray &command, @@ -108,12 +122,14 @@ void PdbEngine::postCommand(const QByteArray &command, const char *callbackName, const QVariant &cookie) { + QTC_ASSERT(m_pdbProc.state() == QProcess::Running, notifyEngineIll()); PdbCommand cmd; cmd.command = command; cmd.callback = callback; cmd.callbackName = callbackName; cmd.cookie = cookie; m_commands.enqueue(cmd); + qDebug() << "ENQUEUE: " << command << cmd.callbackName; showMessage(_(cmd.command), LogInput); m_pdbProc.write(cmd.command + "\n"); } @@ -127,7 +143,6 @@ void PdbEngine::shutdownInferior() void PdbEngine::shutdownEngine() { QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); - SDEBUG("PdbEngine::shutdownEngine()"); m_pdbProc.kill(); } @@ -135,24 +150,8 @@ void PdbEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); - m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath(); - QFile scriptFile(m_scriptFileName); - if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) { - //showMessage("STARTING " +m_scriptFileName + "FAILED"); - showMessage(QString::fromLatin1("Cannot open %1: %2"). - arg(m_scriptFileName, scriptFile.errorString()), LogError); - notifyEngineSetupFailed(); - return; - } - m_pdbProc.disconnect(); // From any previous runs - - m_pdb = _("/usr/bin/python"); + m_pdb = _("python"); showMessage(_("STARTING PDB ") + m_pdb); - QStringList gdbArgs; - gdbArgs += _("-i"); - gdbArgs += _("/usr/bin/pdb"); - gdbArgs += m_scriptFileName; - //gdbArgs += args; connect(&m_pdbProc, SIGNAL(error(QProcess::ProcessError)), SLOT(handlePdbError(QProcess::ProcessError))); @@ -163,13 +162,15 @@ void PdbEngine::setupEngine() connect(&m_pdbProc, SIGNAL(readyReadStandardError()), SLOT(readPdbStandardError())); + connect(this, SIGNAL(outputReady(QByteArray)), + SLOT(handleOutput2(QByteArray)), Qt::QueuedConnection); + // We will stop immediatly, so setup a proper callback. PdbCommand cmd; cmd.callback = &PdbEngine::handleFirstCommand; m_commands.enqueue(cmd); - m_pdbProc.start(m_pdb, gdbArgs); - //qDebug() << "STARTING:" << m_pdb << gdbArgs; + m_pdbProc.start(m_pdb, QStringList() << _("-i")); if (!m_pdbProc.waitForStarted()) { const QString msg = tr("Unable to start pdb '%1': %2") @@ -189,21 +190,33 @@ void PdbEngine::setupEngine() void PdbEngine::setupInferior() { QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); - attemptBreakpointSynchronization(); - showMessage(_("PDB STARTED, INITIALIZING IT")); - const QByteArray dumperSourcePath = - Core::ICore::instance()->resourcePath().toLocal8Bit() + "/gdbmacros/"; - postCommand("execfile('" + dumperSourcePath + "pdumper.py')", - CB(handleLoadDumper)); + QString fileName = QFileInfo(startParameters().executable).absoluteFilePath(); + QFile scriptFile(fileName); + if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) { + showMessageBox(QMessageBox::Critical, tr("Python Error"), + _("Cannot open script file %1:\n%2"). + arg(fileName, scriptFile.errorString())); + notifyInferiorSetupFailed(); + return; + } + notifyInferiorSetupOk(); } void PdbEngine::runEngine() { + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); showStatusMessage(tr("Running requested..."), 5000); - SDEBUG("PdbEngine::runEngine()"); - notifyEngineRunAndInferiorRunOk(); - postCommand("continue", CB(handleUpdateAll)); + const QByteArray dumperSourcePath = + Core::ICore::instance()->resourcePath().toLocal8Bit() + "/gdbmacros/"; + QString fileName = QFileInfo(startParameters().executable).absoluteFilePath(); + postDirectCommand("import sys"); + postDirectCommand("sys.argv.append('" + fileName.toLocal8Bit() + "')"); + postDirectCommand("execfile('/usr/bin/pdb')"); + postDirectCommand("execfile('" + dumperSourcePath + "pdumper.py')"); + attemptBreakpointSynchronization(); + notifyEngineRunAndInferiorStopOk(); + continueInferior(); } void PdbEngine::interruptInferior() @@ -388,7 +401,7 @@ void PdbEngine::loadAllSymbols() void PdbEngine::reloadModules() { - postCommand("qdebug('listmodules')", CB(handleListModules)); + //postCommand("qdebug('listmodules')", CB(handleListModules)); } void PdbEngine::handleListModules(const PdbResponse &response) @@ -549,6 +562,7 @@ void PdbEngine::updateWatchData(const WatchData &data) void PdbEngine::handlePdbError(QProcess::ProcessError error) { + qDebug() << "HANDLE PDB ERROR"; showMessage(_("HANDLE PDB ERROR")); switch (error) { case QProcess::Crashed: @@ -595,6 +609,7 @@ QString PdbEngine::errorMessage(QProcess::ProcessError error) const void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type) { + qDebug() << "PDB FINISHED"; showMessage(_("PDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code)); notifyEngineSpontaneousShutdown(); } @@ -602,35 +617,57 @@ void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type) void PdbEngine::readPdbStandardError() { QByteArray err = m_pdbProc.readAllStandardError(); - qWarning() << "Unexpected pdb stderr:" << err; - showMessage(_("Unexpected pdb stderr: " + err)); + qDebug() << "\nPDB STDERR" << err; + //qWarning() << "Unexpected pdb stderr:" << err; + //showMessage(_("Unexpected pdb stderr: " + err)); + //handleOutput(err); } void PdbEngine::readPdbStandardOutput() { - m_inbuffer.append(m_pdbProc.readAllStandardOutput()); - //qDebug() << "BUFFER FROM: '" << m_inbuffer << "'"; - int pos = 1; - while ((pos = m_inbuffer.indexOf("(Pdb)")) != -1) { - PdbResponse response; - response.data = m_inbuffer.left(pos).trimmed(); - showMessage(_(response.data)); + QByteArray out = m_pdbProc.readAllStandardOutput(); + qDebug() << "\nPDB STDOUT" << out; + handleOutput(out); +} + +void PdbEngine::handleOutput(const QByteArray &data) +{ + //qDebug() << "READ: " << data; + m_inbuffer.append(data); + qDebug() << "BUFFER FROM: '" << m_inbuffer << "'"; + while (true) { + int pos = m_inbuffer.indexOf("(Pdb)"); + if (pos == -1) + pos = m_inbuffer.indexOf(">>>"); + if (pos == -1) + break; + QByteArray response = m_inbuffer.left(pos).trimmed(); m_inbuffer = m_inbuffer.mid(pos + 6); - QTC_ASSERT(!m_commands.isEmpty(), - qDebug() << "RESPONSE: " << response.data; return) - PdbCommand cmd = m_commands.dequeue(); - response.cookie = cmd.cookie; - if (cmd.callback) { - //qDebug() << "EXECUTING CALLBACK " << cmd.callbackName - // << " RESPONSE: " << response.data; - (this->*cmd.callback)(response); - } else { - qDebug() << "NO CALLBACK FOR RESPONSE: " << response.data; - } + emit outputReady(response); + } + qDebug() << "BUFFER LEFT: '" << m_inbuffer << "'"; + //m_inbuffer.clear(); +} + + +void PdbEngine::handleOutput2(const QByteArray &data) +{ + PdbResponse response; + response.data = data; + showMessage(_(data)); + QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return) + PdbCommand cmd = m_commands.dequeue(); + response.cookie = cmd.cookie; + qDebug() << "DEQUE: " << cmd.command << cmd.callbackName; + if (cmd.callback) { + //qDebug() << "EXECUTING CALLBACK " << cmd.callbackName + // << " RESPONSE: " << response.data; + (this->*cmd.callback)(response); + } else { + qDebug() << "NO CALLBACK FOR RESPONSE: " << response.data; } - //qDebug() << "BUFFER LEFT: '" << m_inbuffer << "'"; } - +/* void PdbEngine::handleResponse(const QByteArray &response0) { QByteArray response = response0; @@ -649,7 +686,7 @@ void PdbEngine::handleResponse(const QByteArray &response0) if (pos1 != -1 && pos2 != -1) { int lineNumber = response.mid(pos1 + 1, pos2 - pos1 - 1).toInt(); QByteArray fileName = response.mid(2, pos1 - 2); - qDebug() << " " << pos1 << pos2 << lineNumber << fileName + qDebug() << " " << pos1 << pos2 << lineNumber << fileName << response.mid(pos1 + 1, pos2 - pos1 - 1); StackFrame frame; frame.file = _(fileName); @@ -663,6 +700,7 @@ void PdbEngine::handleResponse(const QByteArray &response0) } qDebug() << "COULD NOT PARSE RESPONSE: '" << response << "'"; } +*/ void PdbEngine::handleFirstCommand(const PdbResponse &response) { @@ -677,6 +715,12 @@ void PdbEngine::handleUpdateAll(const PdbResponse &response) } void PdbEngine::updateAll() +{ + postCommand("bt", CB(handleBacktrace)); + //updateLocals(); +} + +void PdbEngine::updateLocals() { WatchHandler *handler = watchHandler(); @@ -706,7 +750,6 @@ void PdbEngine::updateAll() options += "defaults,"; options.chop(1); - postCommand("bt", CB(handleBacktrace)); postCommand("qdebug('" + options + "','" + handler->expansionRequests() + "','" + handler->typeFormatRequests() + "','" @@ -741,7 +784,7 @@ void PdbEngine::handleBacktrace(const PdbResponse &response) if (pos1 != -1 && pos2 != -1) { int lineNumber = line.mid(pos1 + 1, pos2 - pos1 - 1).toInt(); QByteArray fileName = line.mid(2, pos1 - 2); - //qDebug() << " " << pos1 << pos2 << lineNumber << fileName + //qDebug() << " " << pos1 << pos2 << lineNumber << fileName // << line.mid(pos1 + 1, pos2 - pos1 - 1); StackFrame frame; frame.file = _(fileName); @@ -758,8 +801,8 @@ void PdbEngine::handleBacktrace(const PdbResponse &response) } } const int frameCount = stackFrames.size(); - for (int i = 0; i != frameCount; ++i) - stackFrames[i].level = frameCount - stackFrames[i].level - 1; + for (int i = 0; i != frameCount; ++i) + stackFrames[i].level = frameCount - stackFrames[i].level - 1; stackHandler()->setFrames(stackFrames); // Select current frame. @@ -768,6 +811,8 @@ void PdbEngine::handleBacktrace(const PdbResponse &response) stackHandler()->setCurrentIndex(currentIndex); gotoLocation(stackFrames.at(currentIndex), true); } + + updateLocals(); } void PdbEngine::handleListLocals(const PdbResponse &response) @@ -792,14 +837,6 @@ void PdbEngine::handleListLocals(const PdbResponse &response) handler->insertBulkData(list); } -void PdbEngine::handleLoadDumper(const PdbResponse &response) -{ - Q_UNUSED(response); - //qDebug() << " DUMPERS LOADED '" << response.data << "'"; - //continueInferior(); - notifyInferiorSetupOk(); -} - unsigned PdbEngine::debuggerCapabilities() const { return ReloadModuleCapability; diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index d6778b89dc1..e113afb4392 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -105,6 +105,9 @@ private: bool isSynchroneous() const { return true; } void updateWatchData(const WatchData &data); +signals: + void outputReady(const QByteArray &data); + private: QString errorMessage(QProcess::ProcessError error) const; unsigned debuggerCapabilities() const; @@ -113,10 +116,14 @@ private: Q_SLOT void handlePdbError(QProcess::ProcessError error); Q_SLOT void readPdbStandardOutput(); Q_SLOT void readPdbStandardError(); + Q_SLOT void handleOutput2(const QByteArray &data); void handleResponse(const QByteArray &ba); + void handleOutput(const QByteArray &data); void updateAll(); + void updateLocals(); void handleUpdateAll(const PdbResponse &response); void handleFirstCommand(const PdbResponse &response); + void handleExecuteDebuggerCommand(const PdbResponse &response); typedef void (PdbEngine::*PdbCommandCallback) (const PdbResponse &response); @@ -139,7 +146,6 @@ private: void handleListLocals(const PdbResponse &response); void handleListModules(const PdbResponse &response); void handleListSymbols(const PdbResponse &response); - void handleLoadDumper(const PdbResponse &response); void handleBreakInsert(const PdbResponse &response); void handleChildren(const WatchData &data0, const GdbMi &item, @@ -149,6 +155,7 @@ private: PdbCommandCallback callback = 0, const char *callbackName = 0, const QVariant &cookie = QVariant()); + void postDirectCommand(const QByteArray &command); QQueue<PdbCommand> m_commands; diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp index 54f30904646..6301a8302df 100644 --- a/src/plugins/debugger/script/scriptengine.cpp +++ b/src/plugins/debugger/script/scriptengine.cpp @@ -327,7 +327,8 @@ void ScriptEngine::importExtensions() "Make sure that the bindings have been built, " "and that this executable and the plugins are " "using compatible Qt libraries.", - qPrintable(failExtensions.join(QLatin1String(", "))), qPrintable(dir.absolutePath())); + qPrintable(failExtensions.join(QLatin1String(", "))), + qPrintable(dir.absolutePath())); } } return; // failExtensions.isEmpty(); @@ -336,12 +337,12 @@ void ScriptEngine::importExtensions() void ScriptEngine::runEngine() { QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); - SDEBUG("ScriptEngine::runEngine()"); notifyEngineRunAndInferiorRunOk(); showStatusMessage(tr("Running requested..."), 5000); showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc); importExtensions(); - const QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName); + const QScriptValue result = + m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName); QString msg; if (m_scriptEngine->hasUncaughtException()) { msg = _("An exception occurred during execution at line: %1\n%2\n") diff --git a/tests/manual/gdbdebugger/python/math.py b/tests/manual/gdbdebugger/python/math.py index 52f0cb58a7b..0bd111e386a 100644 --- a/tests/manual/gdbdebugger/python/math.py +++ b/tests/manual/gdbdebugger/python/math.py @@ -46,8 +46,8 @@ def testMath(): print cube(5) def main(): - #testMath() - testApp() + testMath() + #testApp() return 0 if __name__ == '__main__': -- GitLab