diff --git a/share/qtcreator/dumper/bridge.py b/share/qtcreator/dumper/bridge.py index 5a45bbfc627..f6bfcb93cd4 100644 --- a/share/qtcreator/dumper/bridge.py +++ b/share/qtcreator/dumper/bridge.py @@ -68,11 +68,11 @@ if not cdbLoaded: # LLDB if not gdbLoaded and not cdbLoaded: - try: + #try: execfile(os.path.join(currentDir, "lbridge.py")) lldbLoaded = True - except: - failReasons.append(traceback.format_exc()) + #except: + # failReasons.append(traceback.format_exc()) # One is sufficient. diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index 4af8cb5d6af..b0663e6b230 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -1,4 +1,49 @@ -import json + +import inspect +import os +#import traceback + +cdbLoaded = False +lldbLoaded = False +gdbLoaded = False + +####################################################################### +# +# Helpers +# +####################################################################### + +currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) +#print "DIR: %s " % currentDir + +def warn(message): + print "XXX: %s\n" % message.encode("latin1") + +PointerCode = None +ArrayCode = None +StructCode = None +UnionCode = None +EnumCode = None +FlagsCode = None +FunctionCode = None +IntCode = None +FloatCode = None +VoidCode = None +SetCode = None +RangeCode = None +StringCode = None +BitStringCode = None +ErrorTypeCode = None +MethodCode = None +MethodPointerCode = None +MemberPointerCode = None +ReferenceCode = None +CharCode = None +BoolCode = None +ComplexCode = None +TypedefCode = None +NamespaceCode = None +SimpleValueCode = None # LLDB only #warn("LOADING LLDB") @@ -26,9 +71,6 @@ BreakpointOnQmlSignalEmit = 13 BreakpointAtJavaScriptThrow = 14 -def dumpJson(stuff): - warn("%s" % json.dumps(stuff, sort_keys=True, indent=4, separators=(',', ': '))) - def registerCommand(name, func): pass @@ -135,9 +177,9 @@ def locationData(options): return "location={file=\"%s\",line=\"%s\",addr=\"%s\"}," \ % (frame.line_entry.file, frame.line_entry.line, frame.pc) -def stackData(options): +def stackData(options, threadId): try: - thread = lldb.process.GetThreadById(options["threadid"]) + thread = lldb.process.GetThreadById(threadId) except: thread = lldb.process.GetThreadAtIndex(0) result = "stack={frames=[" @@ -156,29 +198,6 @@ def stackData(options): result += "],hasmore=\"%s\"}, " % hasmore return result -def parseOptions(optionstring): - options = {} - for opt in optionstring.split(","): - try: - key, value = opt.split(":") - options[key] = value - except: - pass - return options - -def updateData(parts, localsOptions, stackOptions, threadOptions): - result = "result={"; - if parts & 1: - result += bb(localsOptions) + "," - if parts & 2: - result += stackData(parseOptions(stackOptions)) - if parts & 4: - result += threadsData(parseOptions(threadOptions)) - result += stateData({}) - result += locationData({}) - result += "}" - return result - def listModules(): result = "result={modules=[" for module in lldb.target.modules: @@ -237,8 +256,8 @@ def onBreak(): result = "*stopped,frame={....}" print result -def handleBreakpoints(stuff): - todo = json.loads(stuff) +def handleBreakpoints(opts, toAdd, toChange, toRemove): + #todo = json.loads(stuff) #dumpJson(todo) #target = lldb.debugger.CreateTargetWithFileAndArch (exe, lldb.LLDB_ARCH_DEFAULT) target = lldb.debugger.GetTargetAtIndex(0) @@ -246,7 +265,7 @@ def handleBreakpoints(stuff): result = "result={bkpts={added=[" - for bp in todo["add"]: + for bp in toAdd: bpType = bp["type"] if bpType == BreakpointByFileAndLine: bpNew = target.BreakpointCreateByLocation(str(bp["file"]), int(bp["line"])) @@ -270,7 +289,7 @@ def handleBreakpoints(stuff): result += "],changed=[" - for bp in todo["change"]: + for bp in toChange: bpChange = target.FindBreakpointByID(int(bp["lldbid"])) bpChange.SetIgnoreCount(int(bp["ignorecount"])) bpChange.SetCondition(str(bp["condition"])) @@ -280,7 +299,7 @@ def handleBreakpoints(stuff): result += "],removed=[" - for bp in todo["remove"]: + for bp in toRemove: bpDead = target.BreakpointDelete(int(bp["lldbid"])) result += "{modelid=\"%s\"}" % bp["modelid"] @@ -292,66 +311,70 @@ def doSync(func): func() lldb.debugger.SetAsync(True) -def createReport(): +def createReport(options): result = "result={" - result += stackData({'threadid': lldb.process.selected_thread.id}) + result += bb(options["locals"]) + result += stackData(options["stack"], lldb.process.selected_thread.id) result += threadsData({}) result += stateData({}) result += locationData({}) + result += "token=\"%s\"" % options["token"] result += "}" return result -def executeNext(): +def executeNext(opts): doSync(lldb.thread.StepOver) - return createReport() + return createReport(opts) -def executeNextI(): +def executeNextI(opts): doSync(lldb.thread.StepOver) - return createReport() + return createReport(opts) -def executeStep(): - doSync(lldb.thread.Step) - return createReport() +def executeStep(opts): + lldb.thread.Step() + return createReport(opts) -def executeStepI(): +def executeStepI(opts): doSync(lldb.thread.StepInstOver) - return createReport() + return createReport(opts) -def executeStepOut(): +def executeStepOut(opts): doSync(lldb.thread.StepOut) - return createReport() + return createReport(opts) -def executeRunToLine(): +def executeRunToLine(opts): return "result={error={msg='Not implemented'}}" -def executeJumpToLine(): +def executeJumpToLine(opts): return "result={error={msg='Not implemented'}}" -def continueInferior(): +def continueInferior(opts): #lldb.debugger.HandleCommand("process continue") lldb.process.Continue() return "result={state='running'}" -def interruptInferior(): +def interruptInferior(opts): lldb.debugger.SetAsync(False) lldb.process.Stop() #lldb.process.SendAsyncInterrupt() lldb.debugger.SetAsync(True) return createReport() -def setupInferior(fileName): +def setupInferior(opts, fileName): lldb.debugger.HandleCommand("target create '%s'" % fileName) + return "result={state=\"inferiorsetupok\"}" -def runEngine(): +def runEngine(opts): lldb.debugger.HandleCommand("process launch") + return "result={state=\"enginerunok\"}" -def activateFrame(frame): +def activateFrame(opts, frame): lldb.debugger.HandleCommand("frame select " + frame) -def selectThread(thread): +def selectThread(opts, thread): lldb.debugger.HandleCommand("thread select " + thread) -def requestModuleSymbols(frame): +def requestModuleSymbols(opts, frame): lldb.debugger.HandleCommand("target module list " + frame) @@ -402,3 +425,12 @@ if False: + "stopreason='${thread.stop-reason}'" #+ "returnvalue='${thread.return-value}'" + "\},") + + +lldbLoaded = True + +execfile(os.path.join(currentDir, "dumper.py")) +execfile(os.path.join(currentDir, "qttypes.py")) +bbsetup() + +print "result={state=\"enginesetupok\"}" diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 22dc27f6d64..798780d99a9 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -68,15 +68,6 @@ #include -#define DEBUG_SCRIPT 1 -#if DEBUG_SCRIPT -# define SDEBUG(s) qDebug() << s -#else -# define SDEBUG(s) -#endif -# define XSDEBUG(s) qDebug() << s - - #define CB(callback) &LldbEngine::callback, STRINGIFY(callback) namespace Debugger { @@ -119,44 +110,34 @@ void LldbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguage if (!(languages & CppLanguage)) return; QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); - //XSDEBUG("LldbEngine::executeDebuggerCommand:" << command); if (state() == DebuggerNotReady) { showMessage(_("LLDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command); return; } - QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); - postCommand(command.toLatin1(), CB(handleExecuteDebuggerCommand)); + runCommand("executeDebuggerCommand", '"' + command.toUtf8() + '"'); } -void LldbEngine::handleExecuteDebuggerCommand(const LldbResponse &response) +static int token = 1; + +void LldbEngine::runCommand(const QByteArray &functionName, + const QByteArray &extraArgs) { - Q_UNUSED(response); + runSimpleCommand("script " + functionName + "({" + + currentOptions() + + ",\"token\":" + QByteArray::number(token) + '}' + + (extraArgs.isEmpty() ? "" : ',' + extraArgs) + ')'); } -void LldbEngine::postDirectCommand(const QByteArray &command) +void LldbEngine::runSimpleCommand(const QByteArray &command) { - QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); - showMessage(_(command), LogInput); - m_lldbProc.write(command + '\n'); -} - -void LldbEngine::postCommand(const QByteArray &command, - LldbCommandCallback callback, - const char *callbackName, - const QVariant &cookie) -{ - static int token = 0; - ++token; QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); LldbCommand cmd; - cmd.command = command; - cmd.callback = callback; - cmd.callbackName = callbackName; - cmd.cookie = cookie; cmd.token = token; + cmd.command = command; m_commands.enqueue(cmd); - showMessage(QString::number(token) + _(cmd.command), LogInput); - m_lldbProc.write(cmd.command + '\n'); + showMessage(QString::number(token) + _(command), LogInput); + m_lldbProc.write(command + '\n'); + ++token; } void LldbEngine::shutdownInferior() @@ -188,12 +169,9 @@ void LldbEngine::setupEngine() SLOT(readLldbStandardError())); connect(this, SIGNAL(outputReady(QByteArray)), - SLOT(handleOutput2(QByteArray)), Qt::QueuedConnection); + SLOT(handleResponse(QByteArray)), Qt::QueuedConnection); // We will stop immediately, so setup a proper callback. - LldbCommand cmd; - cmd.callback = &LldbEngine::handleFirstCommand; - m_commands.enqueue(cmd); m_lldbProc.start(m_lldb); @@ -210,28 +188,17 @@ void LldbEngine::setupEngine() return; } - postCommand("script execfile('" + - Core::ICore::resourcePath().toLocal8Bit() + "/dumper/bridge.py')", - CB(handleSetupEngine)); -} + // Dummy callback for initial (lldb) prompt. + m_commands.enqueue(LldbCommand()); -void LldbEngine::handleSetupEngine(const LldbResponse &response) -{ - Q_UNUSED(response); - notifyEngineSetupOk(); + runSimpleCommand("script execfile(\"" + Core::ICore::resourcePath().toUtf8() + + "/dumper/lbridge.py\")"); } void LldbEngine::setupInferior() { QString fileName = QFileInfo(startParameters().executable).absoluteFilePath(); - postCommand("script setupInferior('" + fileName.toUtf8() + "')", - CB(handleInferiorSetup)); -} - -void LldbEngine::handleInferiorSetup(const LldbResponse &response) -{ - Q_UNUSED(response); - notifyInferiorSetupOk(); + runCommand("setupInferior", '"' + fileName.toUtf8() + '"'); } void LldbEngine::runEngine() @@ -244,73 +211,69 @@ void LldbEngine::runEngine() void LldbEngine::runEngine2() { showStatusMessage(tr("Running requested..."), 5000); - postCommand("script runEngine()", CB(handleRunEngine)); -} - -void LldbEngine::handleRunEngine(const LldbResponse &response) -{ - Q_UNUSED(response); - notifyEngineRunAndInferiorRunOk(); + runCommand("runEngine"); } void LldbEngine::interruptInferior() { showStatusMessage(tr("Interrupt requested..."), 5000); - postCommand("script interruptInferior()", CB(handleInferiorInterrupt)); + runCommand("interruptInferior"); } -void LldbEngine::handleInferiorInterrupt(const LldbResponse &response) -{ - Q_UNUSED(response); - notifyInferiorStopOk(); -} +//void LldbEngine::handleInferiorInterrupt(const QByteArray &response) +//{ +// Q_UNUSED(response); +// notifyInferiorStopOk(); +//} void LldbEngine::executeStep() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeStep()", CB(handleResponse)); + runCommand("executeStep"); } void LldbEngine::executeStepI() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeStepI()", CB(handleResponse)); + runCommand("executeStepI"); } void LldbEngine::executeStepOut() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeStepOut()", CB(handleResponse)); + runCommand("executeStepOut"); } void LldbEngine::executeNext() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeNext()", CB(handleResponse)); + runCommand("executeNext"); } void LldbEngine::executeNextI() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeStepNextI()", CB(handleResponse)); + runCommand("executeStepNextI"); } void LldbEngine::continueInferior() { resetLocation(); notifyInferiorRunRequested(); - postCommand("script continueInferior()", CB(handleResponse)); + runCommand("continueInferior"); } -void LldbEngine::handleResponse(const LldbResponse &response) +void LldbEngine::handleResponse(const QByteArray &response) { - GdbMi all = parseResultFromString(response.data); + GdbMi all = parseResultFromString(response); + int token = all.findChild("token").data().toInt(); + Q_UNUSED(token); refreshLocals(all.findChild("data")); refreshStack(all.findChild("stack")); refreshThreads(all.findChild("threads")); @@ -318,30 +281,32 @@ void LldbEngine::handleResponse(const LldbResponse &response) refreshState(all.findChild("state")); refreshLocation(all.findChild("location")); refreshModules(all.findChild("modules")); + refreshBreakpoints(all.findChild("bkpts")); + + performContinuation(); } void LldbEngine::executeRunToLine(const ContextData &data) { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeRunToLine(" + QByteArray::number(data.address) - + ',' + data.fileName.toUtf8() + ')', CB(handleResponse)); + runCommand("executeRunToLine", QByteArray::number(data.address) + + ",'" + data.fileName.toUtf8() + "'"); } void LldbEngine::executeRunToFunction(const QString &functionName) { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeRunToFuntion(" + functionName.toUtf8() + ')', - CB(handleResponse)); + runCommand("executeRunToFunction", '"' + functionName.toUtf8() + '"'); } void LldbEngine::executeJumpToLine(const ContextData &data) { resetLocation(); notifyInferiorRunRequested(); - postCommand("script executeJumpToLine(" + QByteArray::number(data.address) - + ',' + data.fileName.toUtf8() + ')', CB(handleResponse)); + runCommand("executeJumpToLine", QByteArray::number(data.address) + + ',' + data.fileName.toUtf8()); } void LldbEngine::activateFrame(int frameIndex) @@ -350,14 +315,12 @@ void LldbEngine::activateFrame(int frameIndex) if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; - postCommand("script activateFrame(" + QByteArray::number(frameIndex) + ')', - CB(handleResponse)); + runCommand("activateFrame", QByteArray::number(frameIndex)); } void LldbEngine::selectThread(ThreadId threadId) { - postCommand("script selectThread(" + QByteArray::number(threadId.raw()) + ')', - CB(handleResponse)); + runCommand("selectThread", QByteArray::number(threadId.raw())); } bool LldbEngine::acceptsBreakpoint(BreakpointModelId id) const @@ -447,24 +410,10 @@ void LldbEngine::attemptBreakpointSynchronization() if (!done) { showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED")); - if (!toAdd.isEmpty()) - toAdd.chop(1); - if (!toChange.isEmpty()) - toChange.chop(1); - if (!toRemove.isEmpty()) - toRemove.chop(1); - - QByteArray cmd = "script handleBreakpoints('"; - cmd += "{\"add\":[" + toAdd + "]"; - cmd += ",\"change\":[" + toChange + "]"; - cmd += ",\"remove\":[" + toRemove + "]}')"; - postCommand(cmd, CB(handleBreakpointsSynchronized)); + runCommand("handleBreakpoints", + '[' + toAdd + "],[" + toChange + "],[" + toRemove + ']'); } else { showMessage(_("BREAKPOINTS ARE SYNCHRONIZED")); - // d->m_disassemblerAgent.updateBreakpointMarkers(); - //LldbResponse dummy; - //handleBreakpointsSynchronized(dummy); - performContinuation(); } } @@ -521,33 +470,29 @@ void LldbEngine::updateBreakpointData(const GdbMi &bkpt, bool added) } } -void LldbEngine::handleBreakpointsSynchronized(const LldbResponse &response) +void LldbEngine::refreshBreakpoints(const GdbMi &bkpts) { - BreakHandler *handler = breakHandler(); - GdbMi all = parseResultFromString(response.data); - GdbMi bkpts = all.findChild("bkpts"); - GdbMi added = bkpts.findChild("added"); - GdbMi changed = bkpts.findChild("changed"); - GdbMi removed = bkpts.findChild("removed"); - foreach (const GdbMi &bkpt, added.children()) { - BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); - QTC_CHECK(handler->state(id) == BreakpointInsertRequested); - updateBreakpointData(bkpt, true); + if (bkpts.isValid()) { + BreakHandler *handler = breakHandler(); + GdbMi added = bkpts.findChild("added"); + GdbMi changed = bkpts.findChild("changed"); + GdbMi removed = bkpts.findChild("removed"); + foreach (const GdbMi &bkpt, added.children()) { + BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); + QTC_CHECK(handler->state(id) == BreakpointInsertRequested); + updateBreakpointData(bkpt, true); + } + foreach (const GdbMi &bkpt, changed.children()) { + BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); + QTC_CHECK(handler->state(id) == BreakpointChangeRequested); + updateBreakpointData(bkpt, false); + } + foreach (const GdbMi &bkpt, removed.children()) { + BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); + QTC_CHECK(handler->state(id) == BreakpointRemoveRequested); + handler->notifyBreakpointRemoveOk(id); + } } - foreach (const GdbMi &bkpt, changed.children()) { - BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); - QTC_CHECK(handler->state(id) == BreakpointChangeRequested); - updateBreakpointData(bkpt, false); - } - foreach (const GdbMi &bkpt, removed.children()) { - BreakpointModelId id = BreakpointModelId(bkpt.findChild("modelid").data()); - QTC_CHECK(handler->state(id) == BreakpointRemoveRequested); - handler->notifyBreakpointRemoveOk(id); - } - - // Loop. - //attemptBreakpointSynchronization(); - performContinuation(); } void LldbEngine::loadSymbols(const QString &moduleName) @@ -561,7 +506,7 @@ void LldbEngine::loadAllSymbols() void LldbEngine::reloadModules() { - postCommand("script listModules()", CB(handleResponse)); + runCommand("listModules"); } void LldbEngine::refreshModules(const GdbMi &modules) @@ -583,22 +528,22 @@ void LldbEngine::refreshModules(const GdbMi &modules) void LldbEngine::requestModuleSymbols(const QString &moduleName) { - postCommand("script requestModuleSymbols(" + moduleName.toUtf8() + ')', - CB(handleListSymbols), moduleName); + runCommand("requestModuleSymbols", '"' + moduleName.toUtf8() + '"'); } -void LldbEngine::handleListSymbols(const LldbResponse &response) +void LldbEngine::handleListSymbols(const QByteArray &response) { - GdbMi out; - out.fromString(response.data.trimmed()); - Symbols symbols; - QString moduleName = response.cookie.toString(); - foreach (const GdbMi &item, out.children()) { - Symbol symbol; - symbol.name = _(item.findChild("name").data()); - symbols.append(symbol); - } - debuggerCore()->showModuleSymbols(moduleName, symbols); + Q_UNUSED(response); +// GdbMi out; +// out.fromString(response.trimmed()); +// Symbols symbols; +// QString moduleName = response.cookie.toString(); +// foreach (const GdbMi &item, out.children()) { +// Symbol symbol; +// symbol.name = _(item.findChild("name").data()); +// symbols.append(symbol); +// } +// debuggerCore()->showModuleSymbols(moduleName, symbols); } @@ -615,8 +560,8 @@ static QHash m_toolTipCache; bool LldbEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, const DebuggerToolTipContext &ctx) { - Q_UNUSED(mousePos) - Q_UNUSED(editor) + Q_UNUSED(mousePos); + Q_UNUSED(editor); if (state() != InferiorStopOk) { //SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED"); @@ -698,7 +643,7 @@ void LldbEngine::assignValueInDebugger(const Internal::WatchData *, const QStrin { Q_UNUSED(expression); Q_UNUSED(value); - SDEBUG("ASSIGNING: " << (expression + QLatin1Char('=') + value.toString())); + //SDEBUG("ASSIGNING: " << (expression + QLatin1Char('=') + value.toString())); #if 0 m_scriptEngine->evaluate(expression + QLatin1Char('=') + value.toString()); updateLocals(); @@ -815,17 +760,29 @@ void LldbEngine::readLldbStandardOutput() m_inbuffer.append(out); } - qDebug("\nBUFFER FROM: '%s'", quoteUnprintable(m_inbuffer).constData()); + //showMessage(_("Lldb stdout: " + out)); + //qDebug("\nBUFFER FROM: '%s'", quoteUnprintable(m_inbuffer).constData()); while (true) { int pos = m_inbuffer.indexOf("(lldb) "); if (pos == -1) break; QByteArray response = m_inbuffer.left(pos).trimmed(); m_inbuffer = m_inbuffer.mid(pos + 7); - qDebug("\nBUFFER RECOGNIZED: '%s'", quoteUnprintable(response).constData()); + //qDebug("\nBUFFER RECOGNIZED: '%s'", quoteUnprintable(response).constData()); + showMessage(_(response)); + + if (m_commands.isEmpty()) { + QTC_ASSERT(false, qDebug() << "RESPONSE: " << response); + return; + } + + LldbCommand cmd = m_commands.dequeue(); + // FIXME: Find a way to tell LLDB to no echo input. + if (response.startsWith(cmd.command)) + response = response.mid(cmd.command.size()); emit outputReady(response); } - qDebug("\nBUFFER LEFT: '%s'", quoteUnprintable(m_inbuffer).constData()); + //qDebug("\nBUFFER LEFT: '%s'", quoteUnprintable(m_inbuffer).constData()); if (m_inbuffer.isEmpty()) return; @@ -856,45 +813,13 @@ void LldbEngine::readLldbStandardOutput() } } -void LldbEngine::handleOutput2(const QByteArray &data) -{ - LldbResponse response; - response.data = data; - //showMessage(_(data)); - QTC_ASSERT(!m_commands.isEmpty(), qDebug() << "RESPONSE: " << data; return); - LldbCommand cmd = m_commands.dequeue(); - // FIXME: Find a way to tell LLDB to no echo input. - if (response.data.startsWith(cmd.command)) - response.data = response.data.mid(cmd.command.size()); - - response.cookie = cmd.cookie; - qDebug("\nDEQUE: '%s' -> '%s'", cmd.command.constData(), 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; - } -} - -void LldbEngine::handleFirstCommand(const LldbResponse &response) -{ - Q_UNUSED(response); -} - -void LldbEngine::updateAll() -{ - updateData(DataKind(LocalsData | StackData | ThreadData)); -} - -void LldbEngine::updateData(DataKind kind) +QByteArray LldbEngine::currentOptions() const { QByteArray localsOptions; QByteArray stackOptions; QByteArray threadsOptions; - if (kind & LocalsData) { + { QByteArray watchers; //if (!m_toolTipExpression.isEmpty()) // watchers += m_toolTipExpression.toLatin1() @@ -927,18 +852,24 @@ void LldbEngine::updateData(DataKind kind) + "watcher:" + watchers.toHex(); } - if (kind & StackData) { + { int maxdepth = debuggerCore()->action(MaximalStackDepth)->value().toInt(); ThreadId curthread = threadsHandler()->currentThread(); stackOptions += "maxdepth:" + QByteArray::number(maxdepth); stackOptions += ",curthread:" + QByteArray::number(curthread.raw()); } - postCommand("script updateData(" + QByteArray::number(kind) + ',' - + '\'' + localsOptions + "'," - + '\'' + stackOptions + "'," - + '\'' + threadsOptions + "')", - CB(handleResponse)); + QByteArray result; + result += "\"locals\":\"" + localsOptions + '"'; + result += ",\"stack\":\"" + stackOptions + '"'; + result += ",\"threads\":\"" + threadsOptions + '"'; + + return result; +} + +void LldbEngine::updateAll() +{ + runCommand("createReport"); } GdbMi LldbEngine::parseResultFromString(QByteArray out) @@ -1063,6 +994,12 @@ void LldbEngine::refreshState(const GdbMi &reportedState) QByteArray newState = reportedState.data(); if (state() == InferiorRunRequested && newState == "running") notifyInferiorRunOk(); + else if (state() == EngineSetupRequested && newState == "enginesetupok") + notifyEngineSetupOk(); + else if (state() == InferiorSetupRequested && newState == "inferiorsetupok") + notifyInferiorSetupOk(); + else if (state() == EngineRunRequested && newState == "enginerunok") + notifyEngineRunAndInferiorRunOk(); else if (state() != InferiorStopOk && newState == "stopped") notifyInferiorSpontaneousStop(); } diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index cf166582f28..0bb94637ea8 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -47,13 +47,6 @@ class GdbMi; /* A debugger engine for using the lldb command line debugger. */ -class LldbResponse -{ -public: - QByteArray data; - QVariant cookie; -}; - class LldbEngine : public DebuggerEngine { Q_OBJECT @@ -110,7 +103,6 @@ private: void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); void performContinuation(); - void handleResponse(const LldbResponse &response); signals: void outputReady(const QByteArray &data); @@ -123,9 +115,7 @@ private: Q_SLOT void handleLldbError(QProcess::ProcessError error); Q_SLOT void readLldbStandardOutput(); Q_SLOT void readLldbStandardError(); - Q_SLOT void handleOutput2(const QByteArray &data); - void handleSetupEngine(const LldbResponse &response); - void handleResponse(const QByteArray &ba); + Q_SLOT void handleResponse(const QByteArray &data); void refreshAll(const GdbMi &all); void refreshThreads(const GdbMi &threads); void refreshStack(const GdbMi &stack); @@ -134,49 +124,34 @@ private: void refreshState(const GdbMi &state); void refreshLocation(const GdbMi &location); void refreshModules(const GdbMi &modules); - - enum DataKind { LocalsData = 1, StackData = 2, ThreadData = 4 }; + void refreshBreakpoints(const GdbMi &bkpts); void updateAll(); - void updateData(DataKind kind); - void handleUpdateData(const LldbResponse &response); - void handleFirstCommand(const LldbResponse &response); - void handleExecuteDebuggerCommand(const LldbResponse &response); - void handleInferiorSetup(const LldbResponse &response); - void handleRunEngine(const LldbResponse &response); - void handleInferiorInterrupt(const LldbResponse &response); - typedef void (LldbEngine::*LldbCommandCallback) - (const LldbResponse &response); typedef void (LldbEngine::*LldbCommandContinuation)(); struct LldbCommand { - LldbCommand() : callback(0), callbackName(0), token(0) {} - - LldbCommandCallback callback; - const char *callbackName; + LldbCommand() : token(0) {} QByteArray command; - QVariant cookie; int token; }; - void handleStop(const LldbResponse &response); - void handleListLocals(const LldbResponse &response); - void handleListModules(const LldbResponse &response); - void handleListSymbols(const LldbResponse &response); - void handleBreakpointsSynchronized(const LldbResponse &response); + QByteArray currentOptions() const; + void handleStop(const QByteArray &response); + void handleListLocals(const QByteArray &response); + void handleListModules(const QByteArray &response); + void handleListSymbols(const QByteArray &response); + void handleBreakpointsSynchronized(const QByteArray &response); void updateBreakpointData(const GdbMi &bkpt, bool added); - void handleUpdateStack(const LldbResponse &response); - void handleUpdateThreads(const LldbResponse &response); + void handleUpdateStack(const QByteArray &response); + void handleUpdateThreads(const QByteArray &response); void handleChildren(const WatchData &data0, const GdbMi &item, QList *list); - void postCommand(const QByteArray &command, - LldbCommandCallback callback = 0, - const char *callbackName = 0, - const QVariant &cookie = QVariant()); - void postDirectCommand(const QByteArray &command); + void runSimpleCommand(const QByteArray &command); + void runCommand(const QByteArray &function, + const QByteArray &extraArgs = QByteArray()); GdbMi parseResultFromString(QByteArray out); QQueue m_commands;