diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index f82df58bc73..fc46bfe03c4 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -500,6 +500,7 @@ class Dumper: self.currentPrintsAddress = None self.currentChildType = None self.currentChildNumChild = None + self.currentWatchers = {} self.executable_ = None self.charType_ = None @@ -508,11 +509,12 @@ class Dumper: self.charPtrType_ = None self.voidType_ = None self.isShuttingDown_ = False + self.dummyValue = None def extractTemplateArgument(self, typename, index): level = 0 skipSpace = False - inner = "" + inner = '' for c in typename[typename.find('<') + 1 : -1]: if c == '<': inner += c @@ -525,7 +527,7 @@ class Dumper: if index == 0: return inner index -= 1 - inner = "" + inner = '' else: inner += c skipSpace = True @@ -736,11 +738,13 @@ class Dumper: result = 'threads={threads=[' for i in xrange(0, self.process.GetNumThreads()): thread = self.process.GetThreadAtIndex(i) + stopReason = thread.GetStopReason() result += '{id="%d"' % thread.GetThreadID() result += ',index="%s"' % i result += ',details="%s"' % thread.GetQueueName() - result += ',state="%s"' % reasons[thread.GetStopReason()] - result += ',stop-reason="%s"' % thread.GetStopReason() + result += ',stop-reason="%s"' % stopReason + if stopReason >= 0 and stopReason < len(reasons): + result += ',state="%s"' % reasons[stopReason] result += ',name="%s"' % thread.GetName() result += ',frame={' frame = thread.GetFrameAtIndex(0) @@ -931,12 +935,37 @@ class Dumper: def reportVariables(self, _ = None): frame = self.currentThread().GetSelectedFrame() - self.currentIName = "local" + self.currentIName = 'local' self.put('data=[') for value in frame.GetVariables(True, True, False, False): + if self.dummyValue is None: + self.dummyValue = value with SubItem(self, value): self.put('iname="%s",' % self.currentIName) self.putItem(value) + + # 'watchers':[{'id':'watch.0','exp':'23'},...] + if not self.dummyValue is None: + for watcher in self.currentWatchers: + iname = watcher['iname'] + index = iname[iname.find('.') + 1:] + exp = binascii.unhexlify(watcher['exp']) + warn("EXP: %s" % exp) + warn("INDEX: %s" % index) + if exp == "": + self.put('type="",value="",exp=""') + continue + + value = self.dummyValue.CreateValueFromExpression(iname, exp) + #value = self.dummyValue + warn("VALUE: %s" % value) + self.currentIName = 'watch' + with SubItem(self, index): + self.put('exp="%s",' % exp) + self.put('wname="%s",' % binascii.hexlify(exp)) + self.put('iname="%s",' % self.currentIName) + self.putItem(value) + self.put(']') self.report('') @@ -953,6 +982,7 @@ class Dumper: self.reportVariables() def reportRegisters(self, _ = None): + return if self.process is None: self.report('process="none"') else: @@ -1225,13 +1255,19 @@ class Dumper: def setOptions(self, args): self.options = args + def setWatchers(self, args): + self.currentWatchers = args['watchers'] + warn("WATCHERS %s" % self.currentWatchers) + def updateData(self, args): self.expandedINames = set(args['expanded'].split(',')) self.autoDerefPointers = int(args['autoderef']) self.useDynamicType = int(args['dyntype']) # Keep always True for now. #self.passExceptions = args['pe'] - self.reportData() + self.useDynamicType = int(args['dyntype']) + #self.reportData() + self.reportVariables(args) def disassemble(self, args): frame = self.currentFrame(); @@ -1263,6 +1299,18 @@ class Dumper: result += ',contents="%s"}' % binascii.hexlify(contents) self.report(result) + def assignValue(self, args): + exp = binascii.unhexlify(args['exp']) + value = binascii.unhexlify(args['value']) + warn("EXP: %s" % exp) + warn("VALUE: %s" % value) + lhs = self.dummyValue.CreateValueFromExpression("$$lhs", exp) + rhs = self.dummyValue.CreateValueFromExpression("$$rhs", value) + warn("LHS: %s" % lhs) + warn("RHS: %s" % rhs) + #lhs.SetData(rhs.GetData()) + self.reportVariables() + def importDumpers(self, _ = None): result = lldb.SBCommandReturnObject() interpreter = self.debugger.GetCommandInterpreter() diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 2b3af11a484..5a07e40e34d 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -164,6 +164,8 @@ void LldbEngine::setupInferior() { QString executable = QFileInfo(startParameters().executable).absoluteFilePath(); runCommand(Command("setupInferior").arg("executable", executable)); + + requestUpdateWatchers(); } void LldbEngine::runEngine() @@ -676,18 +678,16 @@ void LldbEngine::updateAll() // ////////////////////////////////////////////////////////////////////// -void LldbEngine::assignValueInDebugger(const Internal::WatchData *, const QString &expression, const QVariant &value) +void LldbEngine::assignValueInDebugger(const Internal::WatchData *data, + const QString &expression, const QVariant &value) { - Q_UNUSED(expression); - Q_UNUSED(value); - //SDEBUG("ASSIGNING: " << (expression + QLatin1Char('=') + value.toString())); -#if 0 - m_scriptEngine->evaluate(expression + QLatin1Char('=') + value.toString()); - updateLocals(); -#endif + Q_UNUSED(data); + Command cmd("assignValue"); + cmd.arg("exp", expression.toLatin1().toHex()); + cmd.arg("value", value.toString().toLatin1().toHex()); + runCommand(cmd); } - void LldbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags) { Q_UNUSED(data); @@ -699,12 +699,13 @@ void LldbEngine::updateLocals() { WatchHandler *handler = watchHandler(); + requestUpdateWatchers(); + Command cmd("updateData"); cmd.arg("expanded", handler->expansionRequests()); cmd.arg("typeformats", handler->typeFormatRequests()); cmd.arg("formats", handler->individualFormatRequests()); - QList watcherData; // const QString fileName = stackHandler()->currentFrame().file; // if (!fileName.isEmpty()) { // const QString function = stackHandler()->currentFrame().function; @@ -739,16 +740,6 @@ void LldbEngine::updateLocals() // } // } - QHashIterator it(handler->watcherNames()); - while (it.hasNext()) { - it.next(); - QHash hash; - hash["exp"] = '\'' + it.key() + '\''; - hash["id"] = "'watch." + QByteArray::number(it.value()) + '\''; - watcherData.append(Command::toData(hash)); - } - cmd.args.append("'watchers':" + Command::toData(watcherData) + ','); - const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty(); cmd.arg("passexeptions", alwaysVerbose); cmd.arg("fancy", debuggerCore()->boolSetting(UseDebuggingHelpers)); @@ -839,58 +830,21 @@ void LldbEngine::readLldbStandardOutput() } } -QByteArray LldbEngine::currentOptions() const +void LldbEngine::requestUpdateWatchers() { - QByteArray localsOptions; - QByteArray stackOptions; - QByteArray threadsOptions; - - { - QByteArray watchers; - //if (!m_toolTipExpression.isEmpty()) - // watchers += m_toolTipExpression.toLatin1() - // + '#' + tooltipINameForExpression(m_toolTipExpression.toLatin1()); - - WatchHandler *handler = watchHandler(); - QHash watcherNames = handler->watcherNames(); - QHashIterator it(watcherNames); - while (it.hasNext()) { - it.next(); - if (!watchers.isEmpty()) - watchers += "##"; - watchers += it.key() + "#watch." + QByteArray::number(it.value()); - } - - QByteArray options; - if (debuggerCore()->boolSetting(UseDebuggingHelpers)) - options += "fancy,"; - if (debuggerCore()->boolSetting(AutoDerefPointers)) - options += "autoderef,"; - if (options.isEmpty()) - options += "defaults,"; - options.chop(1); - - localsOptions = "options:" + options + " " - + "vars: " - + "expanded:" + handler->expansionRequests() + " " - + "typeformats:" + handler->typeFormatRequests() + " " - + "formats:" + handler->individualFormatRequests() + " " - + "watcher:" + watchers.toHex(); + WatchHandler *handler = watchHandler(); + QHashIterator it(handler->watcherNames()); + QList watcherData; + while (it.hasNext()) { + it.next(); + QHash hash; + hash["iname"] = "'watch." + QByteArray::number(it.value()) + '\''; + hash["exp"] = '\'' + it.key().toHex() + '\''; + watcherData.append(Command::toData(hash)); } - - { - int maxdepth = debuggerCore()->action(MaximalStackDepth)->value().toInt(); - ThreadId curthread = threadsHandler()->currentThread(); - stackOptions += "maxdepth:" + QByteArray::number(maxdepth); - stackOptions += ",curthread:" + QByteArray::number(curthread.raw()); - } - - QByteArray result; - result += "\"locals\":\"" + localsOptions + '"'; - result += ",\"stack\":\"" + stackOptions + '"'; - result += ",\"threads\":\"" + threadsOptions + '"'; - - return result; + Command cmd("setWatchers"); + cmd.args.append("'watchers':" + Command::toData(watcherData) + ','); + runCommand(cmd); } void LldbEngine::refreshLocals(const GdbMi &vars) @@ -911,10 +865,9 @@ void LldbEngine::refreshLocals(const GdbMi &vars) dummy.iname = child["iname"].data(); GdbMi wname = child["wname"]; if (wname.isValid()) { - // Happens (only) for watched expressions. They are encoded as - // base64 encoded 8 bit data, without quotes - dummy.name = decodeData(wname.data(), Base64Encoded8Bit); - dummy.exp = dummy.name.toUtf8(); + // Happens (only) for watched expressions. + dummy.exp = QByteArray::fromHex(wname.data()); + dummy.name = QString::fromUtf8(dummy.exp); } else { dummy.name = child["name"].toUtf8(); } diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index fe44c1940ad..ff239aeee30 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -134,6 +134,7 @@ private: bool supportsThreads() const { return true; } bool isSynchronous() const { return true; } void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); + void requestUpdateWatchers(); void setRegisterValue(int regnr, const QString &value); void fetchMemory(Internal::MemoryAgent *, QObject *, quint64 addr, quint64 length); @@ -171,7 +172,6 @@ private: typedef void (LldbEngine::*LldbCommandContinuation)(); - QByteArray currentOptions() const; void handleStop(const QByteArray &response); void handleListLocals(const QByteArray &response); void handleListModules(const QByteArray &response);