diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 075975329442959064e72d2ddaca70b9f6763b3e..b8c77556556469a3145ddf2109be620739590fcb 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -2235,8 +2235,12 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT } else { const GdbMi stack = stopReason.findChild("stack"); if (stack.isValid()) { - if (parseStackTrace(stack, sourceStepInto) & ParseStackStepInto) { - executeStep(); // Hit on a frame while step into, see parseStackTrace(). + switch (parseStackTrace(stack, sourceStepInto)) { + case ParseStackStepInto: // Hit on a frame while step into, see parseStackTrace(). + executeStep(); + return; + case ParseStackStepOut: // Hit on a frame with no source while step into. + executeStepOut(); return; } } else { @@ -2872,8 +2876,9 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto) // Parse frames, find current. Special handling for step into: // When stepping into on an actual function (source mode) by executing 't', an assembler // frame pointing at the jmp instruction is hit (noticeable by top function being - // 'ILT+'). If that is the case, execute another 't' to step into the actual function. . + // 'ILT+'). If that is the case, execute another 't' to step into the actual function. // Note that executing 't 2' does not work since it steps 2 instructions on a non-call code line. + // If the operate by instruction flag is set, always use the first frame. int current = -1; bool incomplete; StackFrames frames = parseFrames(data, &incomplete); @@ -2881,9 +2886,15 @@ unsigned CdbEngine::parseStackTrace(const GdbMi &data, bool sourceStepInto) for (int i = 0; i < count; i++) { const bool hasFile = !frames.at(i).file.isEmpty(); // jmp-frame hit by step into, do another 't' and abort sequence. - if (!hasFile && i == 0 && sourceStepInto && frames.at(i).function.contains(QLatin1String("ILT+"))) { - showMessage(QString::fromLatin1("Step into: Call instruction hit, performing additional step..."), LogMisc); - return ParseStackStepInto; + if (!hasFile && i == 0 && sourceStepInto) { + if (frames.at(i).function.contains(QLatin1String("ILT+"))) { + showMessage(QString::fromLatin1("Step into: Call instruction hit, " + "performing additional step..."), LogMisc); + return ParseStackStepInto; + } + showMessage(QString::fromLatin1("Step into: Hit frame with no source, " + "step out..."), LogMisc); + return ParseStackStepOut; } if (hasFile) { const NormalizedSourceFileName fileName = sourceMapNormalizeFileNameFromDebugger(frames.at(i).file); diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index ea740bb215e228b0b550e9f6cfe0eca150693a33..537fc1ba3a1f367c64ec053555e910ace11a8467 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -181,7 +181,8 @@ private: }; enum ParseStackResultFlags // Flags returned by parseStackTrace { - ParseStackStepInto = 1 // Need to execute a step, hit on a call frame in "Step into" + ParseStackStepInto = 1, // Need to execute a step, hit on a call frame in "Step into" + ParseStackStepOut = 2 // Need to step out, hit on a frame without debug information };