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
     };