diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h
index d3bc9d20f4027734d1561338de98b7f26939ef3b..53874f23cc0a48d00f4e0948c420be28f58a564b 100644
--- a/src/plugins/debugger/debuggerconstants.h
+++ b/src/plugins/debugger/debuggerconstants.h
@@ -75,9 +75,11 @@ enum DebuggerState
     InferiorStartFailed,
 
     InferiorRunningRequested,   // Debuggee requested to run
+    InferiorRunningRequested_Kill, // Debuggee requested to run, but want to kill it
     InferiorRunning,            // Debuggee running
 
     InferiorStopping,           // Debuggee running, stop requested
+    InferiorStopping_Kill,      // Debuggee running, stop requested, want to kill it
     InferiorStopped,            // Debuggee stopped
     InferiorStopFailed,         // Debuggee not stopped, will kill debugger
 
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 04330ea2176fb57ea2e2e18b0e832f155d8885e9..0192429b075a596bc9c85c0801800a6256b1c6cc 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -192,9 +192,11 @@ const char *DebuggerManager::stateName(int s)
         SN(InferiorStarting)
         SN(InferiorStartFailed)
         SN(InferiorRunningRequested)
+        SN(InferiorRunningRequested_Kill)
         SN(InferiorRunning)
         SN(InferiorUnrunnable)
         SN(InferiorStopping)
+        SN(InferiorStopping_Kill)
         SN(InferiorStopped)
         SN(InferiorStopFailed)
         SN(InferiorShuttingDown)
@@ -1578,11 +1580,17 @@ static bool isAllowedTransition(int from, int to)
         return to == EngineShuttingDown;
 
     case InferiorRunningRequested:
+        return to == InferiorRunning || to == InferiorStopped
+            || to == InferiorRunningRequested_Kill;
+    case InferiorRunningRequested_Kill:
         return to == InferiorRunning || to == InferiorStopped;
     case InferiorRunning:
         return to == InferiorStopping;
 
     case InferiorStopping:
+        return to == InferiorStopped || to == InferiorStopFailed
+            || to == InferiorStopping_Kill;
+    case InferiorStopping_Kill:
         return to == InferiorStopped || to == InferiorStopFailed;
     case InferiorStopped:
         return to == InferiorRunningRequested || to == InferiorShuttingDown;
@@ -1705,6 +1713,8 @@ bool DebuggerManager::debuggerActionsEnabled() const
     case AdapterStarted:
     case AdapterStartFailed:
     case InferiorStartFailed:
+    case InferiorRunningRequested_Kill:
+    case InferiorStopping_Kill:
     case InferiorStopFailed:
     case InferiorShuttingDown:
     case InferiorShutDown:
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index d36686d3855a2f7bd23ffed74ceecf810f8b8cc7..aa7abd010856aabc8345debe033f644c7f51b043 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -115,8 +115,10 @@ static bool stateAcceptsGdbCommands(DebuggerState state)
     case InferiorStarting:
     case InferiorStartFailed:
     case InferiorRunningRequested:
+    case InferiorRunningRequested_Kill:
     case InferiorRunning:
     case InferiorStopping:
+    case InferiorStopping_Kill:
     case InferiorStopped:
     case InferiorShuttingDown:
     case InferiorShutDown:
@@ -649,6 +651,16 @@ void GdbEngine::interruptInferior()
     m_gdbAdapter->interruptInferior();
 }
 
+void GdbEngine::interruptInferiorTemporarily()
+{
+    interruptInferior();
+    foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak)
+        if (cmd.flags & LosesChild) {
+            setState(InferiorStopping_Kill);
+            break;
+        }
+}
+
 void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
 {
     const qint64 pid = pid0.toLongLong();
@@ -731,12 +743,20 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
             debugMessage(_("QUEUING COMMAND ") + cmd.command);
             m_commandsToRunOnTemporaryBreak.append(cmd);
             if (state() == InferiorStopping) {
+                if (cmd.flags & LosesChild)
+                    setState(InferiorStopping_Kill);
                 debugMessage(_("CHILD ALREADY BEING INTERRUPTED"));
+            } else if (state() == InferiorStopping_Kill) {
+                debugMessage(_("CHILD ALREADY BEING INTERRUPTED (KILL PENDING)"));
             } else if (state() == InferiorRunningRequested) {
+                if (cmd.flags & LosesChild)
+                    setState(InferiorRunningRequested_Kill);
                 debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT"));
+            } else if (state() == InferiorRunningRequested_Kill) {
+                debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)"));
             } else if (state() == InferiorRunning) {
                 showStatusMessage(tr("Stopping temporarily."), 1000);
-                interruptInferior();
+                interruptInferiorTemporarily();
             } else {
                 qDebug() << "ATTEMPTING TO QUEUE COMMAND IN INAPPROPRIATE STATE" << state();
             }
@@ -775,6 +795,9 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
     gdbInputAvailable(LogInput, cmd.command);
 
     m_gdbAdapter->write(cmd.command.toLatin1() + "\r\n");
+
+    if (cmd.flags & LosesChild)
+        setState(InferiorShuttingDown);
 }
 
 void GdbEngine::handleResultRecord(GdbResponse *response)
@@ -888,7 +911,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
     // This is done after the command callbacks so the running-requesting commands
     // can assert on the right state.
     if (state() == InferiorRunning && !m_commandsToRunOnTemporaryBreak.isEmpty())
-        interruptInferior();
+        interruptInferiorTemporarily();
 
     // Continue only if there are no commands wire anymore, so this will
     // be fully synchroneous.
@@ -1075,11 +1098,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
     }
 
     if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
-        QTC_ASSERT(state() == InferiorStopping, qDebug() << state())
+        QTC_ASSERT(state() == InferiorStopping || state() == InferiorStopping_Kill,
+                   qDebug() << state())
         setState(InferiorStopped);
         flushQueuedCommands();
-        QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
-        m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
+        if (state() == InferiorStopped) {
+            QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
+            m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
+        } else {
+            QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state())
+        }
         return;
     }
 
@@ -1320,6 +1348,12 @@ void GdbEngine::handleExecContinue(const GdbResponse &response)
         // The "running" state is picked up in handleResponse()
         QTC_ASSERT(state() == InferiorRunning, /**/);
     } else {
+        if (state() == InferiorRunningRequested_Kill) {
+            setState(InferiorStopped);
+            m_commandsToRunOnTemporaryBreak.clear();
+            shutdown();
+            return;
+        }
         QTC_ASSERT(state() == InferiorRunningRequested, /**/);
         setState(InferiorStopped);
         QByteArray msg = response.data.findChild("msg").data();
@@ -1369,6 +1403,8 @@ void GdbEngine::shutdown()
     case EngineStarting: // We can't get here, really
     case InferiorShuttingDown: // Will auto-trigger further shutdown steps
     case EngineShuttingDown: // Do not disturb! :)
+    case InferiorRunningRequested_Kill:
+    case InferiorStopping_Kill:
         break;
     case AdapterStarting: // GDB is up, adapter is "doing something"
         setState(AdapterStartFailed);
@@ -1388,8 +1424,7 @@ void GdbEngine::shutdown()
     case InferiorStopped:
         // FIXME set some timeout?
         postCommand(_(m_gdbAdapter->inferiorShutdownCommand()),
-                    NeedsStop, CB(handleInferiorShutdown));
-        setState(InferiorShuttingDown); // Do it after posting the command!
+                    NeedsStop | LosesChild, CB(handleInferiorShutdown));
         break;
     case AdapterStarted: // We can't get here, really
     case InferiorStartFailed:
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 665e77688de66b8af9cc5de346f0605a0ad7e858..ab39b4101ca1d0ddae5e36149ab493bd71726f0e 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -176,8 +176,9 @@ private: ////////// Gdb Command Management //////////
         RebuildModel = 4, // Trigger model rebuild when no such commands are pending any more
         WatchUpdate = Discardable | RebuildModel,
         EmbedToken = 8,   // Expand %1 in the command to the command token
-        RunRequest = 16,  // Callback expect GdbResultRunning instead of GdbResultDone
-        ExitRequest = 32  // Callback expect GdbResultExit instead of GdbResultDone
+        RunRequest = 16,  // Callback expects GdbResultRunning instead of GdbResultDone
+        ExitRequest = 32, // Callback expects GdbResultExit instead of GdbResultDone
+        LosesChild = 64   // Auto-set inferior shutdown related states
     };
     Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
     private:
@@ -283,6 +284,7 @@ private: ////////// Inferior Management //////////
     void autoContinueInferior();
     virtual void continueInferior();
     virtual void interruptInferior();
+    void interruptInferiorTemporarily();
 
     virtual void runToLineExec(const QString &fileName, int lineNumber);
     virtual void runToFunctionExec(const QString &functionName);