From e963a43b3296693a30ff7fbd1dc0a73155e5231f Mon Sep 17 00:00:00 2001
From: David Schulz <david.schulz@digia.com>
Date: Wed, 27 Feb 2013 23:59:23 -0800
Subject: [PATCH] CDB: Only step in frame if it has source information.

Change-Id: I9cf1fae00627bb6bf6bdf79cb99fa173df66ad94
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
---
 src/plugins/debugger/cdb/cdbengine.cpp | 23 +++++++++++++++++------
 src/plugins/debugger/cdb/cdbengine.h   |  3 ++-
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 07597532944..b8c77556556 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 ea740bb215e..537fc1ba3a1 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
     };
 
 
-- 
GitLab