diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp index a123dcfef2b..0503bdc232e 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp @@ -94,9 +94,24 @@ void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &respon void AbstractPlainGdbAdapter::runEngine() { QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + m_engine->postCommand("print QString", CB(handleNamespaceExtraction)); m_engine->postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun)); } +void AbstractPlainGdbAdapter::handleNamespaceExtraction(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) { + // $1 = {void (myns::QString * const, const char *)} 0x8058e2c "} + const QByteArray ba = response.data.findChild("consolestreamoutput").data(); + const int posQString = ba.indexOf("QString"); + const int posNs = ba.lastIndexOf('(', posQString) + 1; + const QByteArray ns = ba.mid(posNs, posQString - posNs); + //qDebug() << "BA: " << response.toString() << ba << posQString << posNs << ns; + if (!ns.isEmpty()) + m_engine->setQtNamespace(ns); + } +} + void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response) { QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.h b/src/plugins/debugger/gdb/abstractplaingdbadapter.h index 0d0ccdfdc31..f7746e7624a 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.h +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.h @@ -52,6 +52,7 @@ public: protected: void handleInfoTarget(const GdbResponse &response); + void handleNamespaceExtraction(const GdbResponse &response); private: virtual QByteArray execFilePath() const = 0; @@ -60,7 +61,6 @@ private: virtual QString fromLocalEncoding(const QByteArray &b) const = 0; void handleExecRun(const GdbResponse &response); void handleFileExecAndSymbols(const GdbResponse &response); - }; } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 77e01c98184..9ed40e4e793 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3719,30 +3719,32 @@ void GdbEngine::watchPoint(const QPoint &pnt) { QByteArray x = QByteArray::number(pnt.x()); QByteArray y = QByteArray::number(pnt.y()); - postCommand("print 'QApplication::widgetAt'(" + x + ',' + y + ')', + postCommand("print '" + qtNamespace() + "QApplication::widgetAt'(" + + x + ',' + y + ')', NeedsStop, CB(handleWatchPoint)); } void GdbEngine::handleWatchPoint(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { - GdbMi contents = response.data.findChild("consolestreamoutput"); + const GdbMi contents = response.data.findChild("consolestreamoutput"); // "$5 = (void *) 0xbfa7ebfc\n" - QByteArray ba = parsePlainConsoleStream(response); + const QByteArray ba = parsePlainConsoleStream(response); + //qDebug() << "BA: " << ba; const int posWidget = ba.indexOf("QWidget"); - if (posWidget == -1) - return; const int posNs = ba.lastIndexOf(' ', posWidget) + 1; - if (posNs == 0) - return; const int pos0x = ba.indexOf("0x", posWidget + 7); - if (pos0x == -1) - return; - const QByteArray addr = ba.mid(pos0x); - const QByteArray ns = ba.mid(posNs, posWidget - posNs); - const QByteArray type = ns.isEmpty() ? "QWidget*" : ("'" + ns + "QWidget'*"); - const QString exp = _("(*(%1)%2)").arg(_(type)).arg(_(addr)); - watchHandler()->watchExpression(exp); + if (posWidget == -1 || posNs == 0 || pos0x == -1) { + showStatusMessage(tr("Cannot read widget data: %1").arg(_(ba))); + } else { + const QByteArray addr = ba.mid(pos0x); + //const QByteArray ns = ba.mid(posNs, posWidget - posNs); + const QByteArray ns = qtNamespace(); + const QByteArray type = ns.isEmpty() ? "QWidget*" : ("'" + ns + "QWidget'*"); + const QString exp = _("(*(%1)%2)").arg(_(type)).arg(_(addr)); + // qDebug() << posNs << posWidget << pos0x << addr << ns << type; + watchHandler()->watchExpression(exp); + } } } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index d9ab60bf71e..728aad35bd7 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -116,6 +116,8 @@ private: ////////// General Interface ////////// virtual void executeDebuggerCommand(const QString &command); virtual QByteArray qtNamespace() const { return m_dumperHelper.qtNamespace(); } + virtual void setQtNamespace(const QByteArray &ns) + { return m_dumperHelper.setQtNamespace(ns); } private: ////////// General State ////////// diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index b38ff7e74dc..d11f0465e23 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -970,7 +970,8 @@ bool QtDumperHelper::parseQuery(const GdbMi &contents) qDebug() << "parseQuery" << contents.toString(true, 2); // Common info, dumper version, etc - m_qtNamespace = contents.findChild("namespace").data(); + QByteArray ns = contents.findChild("namespace").data(); + setQtNamespace(ns); int qtv = 0; const GdbMi qtversion = contents.findChild("qtversion"); if (qtversion.children().size() == 3) { diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h index a696041c1ec..09bfe6caf5f 100644 --- a/src/plugins/debugger/watchutils.h +++ b/src/plugins/debugger/watchutils.h @@ -172,6 +172,8 @@ public: int qtVersion() const; QByteArray qtVersionString() const; QByteArray qtNamespace() const; + void setQtNamespace(const QByteArray &ba) + { if (!ba.isEmpty()) m_qtNamespace = ba; } // Complete parse of "query" (protocol 1) response from debuggee buffer. // 'data' excludes the leading indicator character.