diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 651719dfffb..7d825014cd6 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -1107,13 +1107,53 @@ class Dumper(DumperBase): return isNativeMixed = int(args.get('nativemixed', 0)) + extraQml = int(args.get('extraqml', '0')) limit = args.get('stacklimit', -1) (n, isLimited) = (limit, True) if limit > 0 else (thread.GetNumFrames(), False) self.currentCallContext = None result = 'stack={current-thread="%d"' % thread.GetThreadID() result += ',frames=[' - for i in range(n): + + ii = 0 + if extraQml: + ns = self.qtNamespace() + needle = self.qtNamespace() + 'QV4::ExecutionEngine' + pats = [ + '{0}qt_v4StackTraceForEngine((void*)0x{1:x})', + '{0}qt_v4StackTrace((({0}QV4::ExecutionEngine *)0x{1:x})->currentContext())', + '{0}qt_v4StackTrace((({0}QV4::ExecutionEngine *)0x{1:x})->currentContext)', + ] + done = False + while ii < n and not done: + res = None + frame = thread.GetFrameAtIndex(ii) + for variable in frame.GetVariables(True, True, False, True): + if not variable.GetType().IsPointerType(): + continue + derefvar = variable.Dereference() + if derefvar.GetType().GetName() != needle: + continue + addr = derefvar.GetLoadAddress() + for pat in pats: + exp = pat.format(ns, addr) + val = frame.EvaluateExpression(exp) + err = val.GetError() + res = str(val) + if err.Fail(): + continue + pos = res.find('"stack=[') + if pos == -1: + continue + res = res[pos + 8:-2] + res = res.replace('\\\"', '\"') + res = res.replace('func=', 'function=') + result += res + done = True + break + ii += 1 + + for i in range(n - ii): frame = thread.GetFrameAtIndex(i) if not frame.IsValid(): isLimited = False diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index a934c150bf9..dbccf3f880d 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -715,27 +715,6 @@ void LldbEngine::updateAll() runCommand(cmd); } -void LldbEngine::reloadFullStack() -{ - fetchStack(-1); -} - -void LldbEngine::fetchStack(int limit) -{ - DebuggerCommand cmd("fetchStack"); - cmd.arg("nativemixed", isNativeMixedActive()); - cmd.arg("stacklimit", limit); - cmd.arg("context", stackHandler()->currentFrame().context); - cmd.callback = [this](const DebuggerResponse &response) { - const GdbMi &stack = response.data["stack"]; - const bool isFull = !stack["hasmore"].toInt(); - stackHandler()->setFramesAndCurrentIndex(stack["frames"], isFull); - activateFrame(stackHandler()->currentIndex()); - }; - runCommand(cmd); -} - - ////////////////////////////////////////////////////////////////////// // // Watch specific stuff @@ -980,6 +959,33 @@ void LldbEngine::reloadDebuggingHelpers() updateAll(); } +void LldbEngine::loadAdditionalQmlStack() +{ + fetchStack(-1, true); +} + +void LldbEngine::reloadFullStack() +{ + fetchStack(-1, false); +} + +void LldbEngine::fetchStack(int limit, bool extraQml) +{ + DebuggerCommand cmd("fetchStack"); + cmd.arg("nativemixed", isNativeMixedActive()); + cmd.arg("stacklimit", limit); + cmd.arg("context", stackHandler()->currentFrame().context); + cmd.arg("extraqml", int(extraQml)); + cmd.callback = [this](const DebuggerResponse &response) { + const GdbMi &stack = response.data["stack"]; + const bool isFull = !stack["hasmore"].toInt(); + stackHandler()->setFramesAndCurrentIndex(stack["frames"], isFull); + activateFrame(stackHandler()->currentIndex()); + }; + runCommand(cmd); +} + + void LldbEngine::fetchDisassembler(DisassemblerAgent *agent) { QPointer p(agent); @@ -1090,7 +1096,8 @@ bool LldbEngine::hasCapability(unsigned cap) const | OperateByInstructionCapability | RunToLineCapability | WatchComplexExpressionsCapability - | MemoryAddressCapability)) + | MemoryAddressCapability + | AdditionalQmlStackCapability)) return true; if (runParameters().startMode == AttachToCore) diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 95da756880c..fa2becb7424 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -101,6 +101,7 @@ private: void reloadSourceFiles() override {} void reloadFullStack() override; void reloadDebuggingHelpers() override; + void loadAdditionalQmlStack() override; void fetchDisassembler(Internal::DisassemblerAgent *) override; void setRegisterValue(const QString &name, const QString &value) override; @@ -125,7 +126,7 @@ private: void updateAll() override; void doUpdateLocals(const UpdateParameters ¶ms) override; void updateBreakpointData(const Breakpoint &bp, const GdbMi &bkpt, bool added); - void fetchStack(int limit); + void fetchStack(int limit, bool alsoQml = false); void runCommand(const DebuggerCommand &cmd) override; void debugLastCommand() override;