diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 7ffc59ff90c230c5576b6e08d1271523714d3579..7b3d7b838ecb8d782e4d7eb53c1adb7262ed5d3e 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -9,7 +9,7 @@ import gdb import base64 import curses.ascii -# only needed for gdb 7.0 +# only needed for gdb 7.0/7.0.1 that do not implement parse_and_eval import os import tempfile @@ -428,23 +428,20 @@ class FrameCommand(gdb.Command): watchers = base64.b16decode(args[2], True) if len(watchers) > 0: for watcher in watchers.split("##"): - (exp, name) = watcher.split("#") - self.handleWatch(d, exp, name) + (exp, iname) = watcher.split("#") + self.handleWatch(d, exp, iname) d.pushOutput() watchers = d.safeoutput - print('locals={iname="local",name="Locals",value=" ",type=" ",' - + 'children=[' + locals + ']},' - + 'watchers={iname="watch",name="Watchers",value=" ",type=" ",' - + 'children=[' + watchers + ']}\n') + print('data=[' + locals + ',' + watchers + ']\n') - def handleWatch(self, d, exp, name): - #warn("HANDLING WATCH %s, NAME: %s" % (exp, name)) + def handleWatch(self, d, exp, iname): + #warn("HANDLING WATCH %s, INAME: '%s'" % (exp, iname)) if exp.startswith("["): - #warn("EVAL: EXP: %s" % exp) + warn("EVAL: EXP: %s" % exp) d.beginHash() - d.put('iname="watch.%s",' % name) + d.put('iname="%s",' % iname) d.put('name="%s",' % exp) d.put('exp="%s",' % exp) try: @@ -457,7 +454,7 @@ class FrameCommand(gdb.Command): d.beginChildren(len(list)) itemNumber = 0 for item in list: - self.handleWatch(d, item, "%s.%d" % (name, itemNumber)) + self.handleWatch(d, item, "%s.%d" % (iname, itemNumber)) itemNumber += 1 d.endChildren() except: @@ -471,7 +468,7 @@ class FrameCommand(gdb.Command): return d.beginHash() - d.put('iname="watch.%s",' % name) + d.put('iname="%s",' % iname) d.put('name="%s",' % exp) d.put('exp="%s",' % exp) handled = False @@ -481,7 +478,7 @@ class FrameCommand(gdb.Command): else: try: value = parseAndEvaluate(exp) - item = Item(value, "watch.%s" % name, None, None) + item = Item(value, iname, None, None) d.putItemHelper(item) except RuntimeError: d.put(',value="<invalid>",') diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 12210caf44e10d18f9aa4fd44d8a484985920f1e..74749e057d2af79ff8dbae0ecec28b8cb26b2278 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -105,6 +105,14 @@ namespace Internal { #define CB(callback) &GdbEngine::callback, STRINGIFY(callback) +static QByteArray tooltipINameForExpression(const QByteArray &exp) +{ + // FIXME: 'exp' can contain illegal characters + //return "tooltip." + exp; + Q_UNUSED(exp) + return "tooltip.x"; +} + static bool stateAcceptsGdbCommands(DebuggerState state) { switch (state) { @@ -2726,14 +2734,6 @@ bool GdbEngine::supportsThreads() const static QString m_toolTipExpression; static QPoint m_toolTipPos; -static QByteArray tooltipINameForExpression(const QByteArray &exp) -{ - // FIXME: 'exp' can contain illegal characters - //return "tooltip." + exp; - Q_UNUSED(exp) - return "tooltip.x"; -} - bool GdbEngine::showToolTip() { WatchHandler *handler = manager()->watchHandler(); @@ -2765,6 +2765,9 @@ void GdbEngine::setToolTipExpression(const QPoint &mousePos, m_toolTipPos = mousePos; int line, column; QString exp = cppExpressionAt(editor, cursorPos, &line, &column); + if (exp == m_toolTipExpression) + return; + m_toolTipExpression = exp; // FIXME: enable caching @@ -2823,6 +2826,11 @@ void GdbEngine::setToolTipExpression(const QPoint &mousePos, } */ + if (isSynchroneous()) { + updateLocals(QVariant()); + return; + } + WatchData toolTip; toolTip.exp = exp.toLatin1(); toolTip.name = exp; @@ -3608,7 +3616,7 @@ void GdbEngine::updateLocals(const QVariant &cookie) if (isSynchroneous()) { m_processedNames.clear(); manager()->watchHandler()->beginCycle(); - m_toolTipExpression.clear(); + //m_toolTipExpression.clear(); WatchHandler *handler = m_manager->watchHandler(); QByteArray expanded; @@ -3630,10 +3638,13 @@ void GdbEngine::updateLocals(const QVariant &cookie) if (!watchers.isEmpty()) watchers += "##"; if (it.key() == WatchHandler::watcherEditPlaceHolder().toLatin1()) - watchers += "<Edit>#" + QByteArray::number(it.value()); + watchers += "<Edit>#watch." + QByteArray::number(it.value()); else - watchers += it.key() + '#' + QByteArray::number(it.value()); + watchers += it.key() + "#watch." + QByteArray::number(it.value()); } + if (!m_toolTipExpression.isEmpty()) + watchers += "##" + m_toolTipExpression.toLatin1() + + "#" + tooltipINameForExpression(m_toolTipExpression.toLatin1()); QByteArray options; if (theDebuggerBoolSetting(UseDebuggingHelpers)) @@ -3679,7 +3690,7 @@ void GdbEngine::handleStackFrame(const GdbResponse &response) while (out.endsWith(' ') || out.endsWith('\n')) out.chop(1); //qDebug() << "SECOND CHUNK: " << out; - int pos = out.indexOf("locals="); + int pos = out.indexOf("data="); if (pos != 0) { qDebug() << "DISCARDING JUNK AT BEGIN OF RESPONSE: " << out.left(pos); @@ -3687,27 +3698,21 @@ void GdbEngine::handleStackFrame(const GdbResponse &response) } GdbMi all; all.fromStringMultiple(out); + //qDebug() << "ALL: " << all.toString(); - GdbMi locals = all.findChild("locals"); - WatchData *data = manager()->watchHandler()->findItem("local"); - QTC_ASSERT(data, return); + GdbMi data = all.findChild("data"); QList<WatchData> list; - handleChildren(*data, locals, &list); - //for (int i = 0; i != list.size(); ++i) - // qDebug() << "LOCAL: " << list.at(i).toString(); + foreach (const GdbMi &child, data.children()) { + WatchData dummy; + dummy.iname = child.findChild("iname").data(); + dummy.name = _(child.findChild("name").data()); + //qDebug() << "CHILD: " << child.toString(); + handleChildren(dummy, child, &list); + } manager()->watchHandler()->insertBulkData(list); - - GdbMi watchers = all.findChild("watchers"); - data = manager()->watchHandler()->findItem("watch"); - QTC_ASSERT(data, return); - list.clear(); - handleChildren(*data, watchers, &list); //for (int i = 0; i != list.size(); ++i) - // qDebug() << "WATCH: " << list.at(i).toString(); - manager()->watchHandler()->insertBulkData(list); + // qDebug() << "LOCAL: " << list.at(i).toString(); - // FIXME: - //manager()->watchHandler()->updateWatchers(); PENDING_DEBUG("AFTER handleStackFrame()"); // FIXME: This should only be used when updateLocals() was // triggered by expanding an item in the view. diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 91d87d8c7e7589a0d4a8c93f2b74d647072119cc..8028695349c08aa02c300302701b6e85cae1ce4f 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -1517,10 +1517,10 @@ WatchModel *WatchHandler::modelForIName(const QByteArray &iname) const { if (iname.startsWith("local")) return m_locals; - if (iname.startsWith("watch")) - return m_watchers; if (iname.startsWith("tooltip")) return m_tooltips; + if (iname.startsWith("watch")) + return m_watchers; QTC_ASSERT(false, qDebug() << "INAME: " << iname); return 0; }