diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index 70f13a622f13fe6783e4249b38aee9070d2daedb..c36e328fcf9dac7ad8df4d7c3a02f0e0bc8f1544 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -1223,7 +1223,9 @@ void DebuggerEnginePrivate::doShutdownEngine()
 {
     SDEBUG(Q_FUNC_INFO);
     QTC_ASSERT(state() == InferiorShutdownOk
-        || state() == InferiorShutdownFailed, qDebug() << state());
+        || state() == InferiorShutdownFailed
+        || state() == InferiorSetupFailed,
+        qDebug() << state());
     m_targetState = DebuggerFinished;
     m_engine->setState(EngineShutdownRequested);
     m_engine->shutdownEngine();
diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h
index 955f1f533a8e4af75d56ac79214533e6e71348c0..116226f2e34bfda912564ddca553984113c6676e 100644
--- a/src/plugins/debugger/gdb/abstractgdbadapter.h
+++ b/src/plugins/debugger/gdb/abstractgdbadapter.h
@@ -89,8 +89,6 @@ public:
 protected:
     DebuggerState state() const
         { return m_engine->state(); }
-    void setState(DebuggerState state)
-        { m_engine->setState(state); }
     const DebuggerStartParameters &startParameters() const
         { return m_engine->startParameters(); }
     void showMessage(const QString &msg, int channel = LogDebug, int timeout = 1)
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp
index a34f6562a99463ff9f5b5e9e5c60929d27aff21d..935f30e4962c79ee152451c17b170ebf4b95d290 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp
@@ -77,7 +77,11 @@ void AttachGdbAdapter::setupInferior()
 void AttachGdbAdapter::runEngine()
 {
     QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
-    m_engine->notifyInferiorStopOk();
+    m_engine->notifyEngineRunAndInferiorStopOk();
+    m_engine->notifyInferiorRunRequested();
+    m_engine->continueInferiorInternal();
+    m_engine->showStatusMessage(tr("Attached to process %1.")
+        .arg(m_engine->inferiorPid()));
 }
 
 void AttachGdbAdapter::handleAttach(const GdbResponse &response)
@@ -87,7 +91,7 @@ void AttachGdbAdapter::handleAttach(const GdbResponse &response)
         showMessage(_("INFERIOR ATTACHED"));
         showMessage(msgAttachedToStoppedInferior(), StatusBar);
         m_engine->handleInferiorPrepared();
-        m_engine->updateAll();
+        //m_engine->updateAll();
     } else {
         QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
         m_engine->notifyInferiorSetupFailed(msg);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 38651fcaee0d36a462490f40964f0ab7b0b97889..7395d2a4c66d87092819bbb2b4c661bcf6b1249c 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1073,7 +1073,7 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response)
     } else if (response.resultClass == GdbResultDone) {
         // This happens on old gdb. Trigger the effect of a '*stopped'.
         showStatusMessage(tr("Jumped. Stopped"));
-        setState(InferiorStopOk);
+        notifyInferiorSpontaneousStop();
         handleStop1(response);
     }
 }
@@ -1091,7 +1091,7 @@ void GdbEngine::handleExecuteRunToLine(const GdbResponse &response)
         //>122^done
         gotoLocation(m_targetFrame, true);
         showStatusMessage(tr("Target line hit. Stopped"));
-        setState(InferiorStopOk);
+        notifyInferiorSpontaneousStop();
         handleStop1(response);
     }
 }
@@ -1712,7 +1712,7 @@ void GdbEngine::handleGdbExit(const GdbResponse &response)
         postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit));
         break;
     case InferiorSetupRequested: // This may take some time, so just short-circuit it
-        setState(InferiorSetupFailed);
+        notifyInferiorSetupFailed();
         gdbProc()->kill();
         break;
     case InferiorStopFailed: // Tough luck, I guess. But unreachable as of now anyway.
@@ -1725,7 +1725,13 @@ void GdbEngine::detachDebugger()
 {
     QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
     QTC_ASSERT(startMode() != AttachCore, qDebug() << startMode());
-    postCommand("detach");
+    postCommand("detach", GdbEngine::ExitRequest, CB(handleDetach));
+}
+
+void GdbEngine::handleDetach(const GdbResponse &response)
+{
+    Q_UNUSED(response);
+    QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
     notifyInferiorExited();
 }
 
@@ -1737,8 +1743,8 @@ void GdbEngine::quitDebugger()
     // and regular the inferior shutdown procedure could take a while.
     // And the RunControl::stop() is called synchroneously.
     shutdownEngine();
-    initializeVariables();
-    setState(DebuggerNotReady);
+    //initializeVariables();
+    //setState(DebuggerNotReady);
 }
 
 int GdbEngine::currentFrame() const
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index abb906db3525c6a66009a2fe76973cb04130fe25..52731688a440e5ba209aa97df18c9e7061a95ff6 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -490,6 +490,7 @@ private: ////////// View & Data Stuff //////////
     void handleDebuggingHelperEditValue(const GdbResponse &response);
     void handleDebuggingHelperSetup(const GdbResponse &response);
     void handleDebuggingHelperVersionCheckClassic(const GdbResponse &response);
+    void handleDetach(const GdbResponse &response);
 
     Q_SLOT void createFullBacktrace();
     void handleCreateFullBacktrace(const GdbResponse &response);
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index 6e9bc9b869a2b3a05562750ac979ba7309d1959d..598bbde92e1d38ec79072cccd6f9c79db7a1436c 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -210,7 +210,7 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
 {
     QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
     if (record.resultClass == GdbResultDone) {
-        setState(InferiorStopOk);
+        m_engine->notifyInferiorStopOk();
         // gdb server will stop the remote application itself.
         showMessage(_("INFERIOR STARTED"));
         showMessage(msgAttachedToStoppedInferior(), StatusBar);
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index e865b975e37982468c4c75b52475f2f6eab5e6d7..e4a0e59899f728c730cf7bcf191e69b01a27b3d7 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -1604,7 +1604,7 @@ void TrkGdbAdapter::handleTargetRemote(const GdbResponse &record)
 {
     QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
     if (record.resultClass == GdbResultDone) {
-        setState(InferiorStopOk);
+        m_engine->notifyInferiorStopOk();
         m_engine->handleInferiorPrepared();
     } else {
         QString msg = tr("Connecting to TRK server adapter failed:\n")