diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 203bfc5b6b9e8b85671520fe615268fc89668633..2f665f3da53fa677455c3d91ba45c3c80a084b9d 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -150,7 +150,6 @@ void DebuggerManager::init()
 {
     m_status = -1;
     m_busy = false;
-    m_shutdown = false;
 
     m_attachedPID = 0;
     m_startMode = startInternal;
@@ -578,7 +577,7 @@ void DebuggerManager::notifyInferiorExited()
 void DebuggerManager::notifyInferiorPidChanged(int pid)
 {
     //QMessageBox::warning(0, "PID", "PID: " + QString::number(pid)); 
-    qDebug() << "PID: " << pid; 
+    //qDebug() << "PID: " << pid; 
     emit inferiorPidChanged(pid);
 }
 
@@ -590,9 +589,10 @@ void DebuggerManager::showApplicationOutput(const QString &str)
 void DebuggerManager::shutdown()
 {
     //qDebug() << "DEBUGGER_MANAGER SHUTDOWN START";
-    m_shutdown = true;
-    if (m_engine)
+    if (m_engine) {
+        //qDebug() << "SHUTTING DOWN ENGINE" << m_engine;
         m_engine->shutdown();
+    }
     m_engine = 0;
 
     delete scriptEngine;
@@ -835,10 +835,9 @@ void DebuggerManager::cleanupViews()
 
 void DebuggerManager::exitDebugger()
 {
-    if (m_shutdown)
-        return;
-    QTC_ASSERT(m_engine, return);
-    m_engine->exitDebugger();
+    //qDebug() << "DebuggerManager::exitDebugger";
+    if (m_engine)
+        m_engine->exitDebugger();
     cleanupViews();
     setStatus(DebuggerProcessNotReady);
     setBusyCursor(false);
@@ -960,33 +959,6 @@ void DebuggerManager::dumpLog()
     ts << m_outputWindow->combinedContents();
 }
 
-#if 0
-// call after m_gdbProc exited.
-void GdbEngine::procFinished()
-{
-    //qDebug() << "GDB PROCESS FINISHED";
-    setStatus(DebuggerProcessNotReady);
-    showStatusMessage(tr("Done"), 5000);
-    q->m_breakHandler->procFinished();
-    q->m_watchHandler->cleanup();
-    m_stackHandler->m_stackFrames.clear();
-    m_stackHandler->resetModel();
-    m_threadsHandler->resetModel();
-    if (q->m_modulesHandler)
-        q->m_modulesHandler->procFinished();
-    q->resetLocation();
-    setStatus(DebuggerProcessNotReady);
-    emit q->previousModeRequested();
-    emit q->debuggingFinished();
-    //exitDebugger();
-    //showStatusMessage("Gdb killed");
-    m_shortToFullName.clear();
-    m_fullToShortName.clear();
-    m_shared = 0;
-    q->m_busy = false;
-}
-#endif
-
 void DebuggerManager::addToWatchWindow()
 {
     // requires a selection, but that's the only case we want...
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index bd10b7b025967d1793f5145304fd702dcaa0b46f..a3407a0aa59c4f410d3a711929805d872f6d972e 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -466,8 +466,6 @@ private:
     IDebuggerEngine *engine();
     IDebuggerEngine *m_engine;
     DebuggerSettings m_settings;
-    // set during application shutdown
-    bool m_shutdown;
 };
 
 } // namespace Internal
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index 21313428aefbdc14eca3592321211140176a10b4..5034a0d9a4abd0dfe7d9c958c7255dc39e566d69 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -115,6 +115,8 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
     connect(m_manager, SIGNAL(inferiorPidChanged(qint64)),
             this, SLOT(bringApplicationToForeground(qint64)),
             Qt::QueuedConnection);
+    connect(this, SIGNAL(stopRequested()),
+            m_manager, SLOT(exitDebugger()));
 }
 
 void DebuggerRunControl::start()
@@ -148,17 +150,21 @@ void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
 
 void DebuggerRunControl::stop()
 {
-    m_manager->exitDebugger();
+    //qDebug() << "DebuggerRunControl::stop";
+    m_running = false;
+    emit stopRequested();
 }
 
 void DebuggerRunControl::debuggingFinished()
 {
     m_running = false;
+    //qDebug() << "DebuggerRunControl::finished";
     //emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable));
     emit finished();
 }
 
 bool DebuggerRunControl::isRunning() const
 {
+    //qDebug() << "DebuggerRunControl::isRunning" << m_running;
     return m_running;
 }
diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h
index 0c6d979c0107f89e79ce196beb4511ac5e577abb..7b73178d1031df8a7875ab9f4eba3c56cf47dfed 100644
--- a/src/plugins/debugger/debuggerrunner.h
+++ b/src/plugins/debugger/debuggerrunner.h
@@ -82,6 +82,9 @@ public:
     virtual void stop();
     virtual bool isRunning() const;
 
+signals:
+    void stopRequested();
+
 private slots:
     void debuggingFinished();
     void slotAddToOutputWindowInline(const QString &output);
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 0641dac2114aeb7bcf20bb2a35ac90c189adf41f..7f99a0a9b3e2e170c619a38b58038847a27cc2e6 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -257,6 +257,8 @@ GdbEngine::GdbEngine(DebuggerManager *parent)
 
 GdbEngine::~GdbEngine()
 {
+    // prevent sending error messages afterwards
+    m_gdbProc.disconnect(this);
 }
 
 void GdbEngine::initializeConnections()
@@ -386,6 +388,11 @@ void GdbEngine::readDebugeeOutput(const QByteArray &data)
             data.constData(), data.length(), &m_outputCodecState));
 }
 
+void GdbEngine::debugMessage(const QString &msg)
+{
+    emit gdbOutputAvailable("debug:", msg);
+}
+
 // called asyncronously as response to Gdb stdout output in
 // gdbResponseAvailable()
 void GdbEngine::handleResponse()
@@ -656,7 +663,7 @@ void GdbEngine::interruptInferior()
     sendCommand("-exec-interrupt", GdbExecInterrupt);
     qq->notifyInferiorStopped();
 #else
-    qDebug() << "CANNOT STOP INFERIOR" << m_gdbProc.pid();
+    debugMessage(QString("CANNOT STOP INFERIOR %1").arg(m_gdbProc.pid()));
     if (interruptChildProcess(m_gdbProc.pid()))
         qq->notifyInferiorStopped();
 #endif
@@ -666,12 +673,12 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
 {
     int pid = pid0.toInt();
     if (pid == 0) {
-        qDebug() << "Cannot parse PID from " << pid0;
+        debugMessage(QString("Cannot parse PID from %1").arg(pid0));
         return;
     }
     if (pid == q->m_attachedPID)
         return;
-    qDebug() << "FOUND PID  " << pid;
+    debugMessage(QString("FOUND PID %1").arg(pid));
     q->m_attachedPID = pid;
     qq->notifyInferiorPidChanged(pid); 
 }
@@ -686,7 +693,7 @@ void GdbEngine::sendCommand(const QString &command, int type,
     const QVariant &cookie, bool needStop, bool synchronized)
 {
     if (m_gdbProc.state() == QProcess::NotRunning) {
-        //qDebug() << "NO GDB PROCESS RUNNING, CMD IGNORED:" << command;
+        debugMessage("NO GDB PROCESS RUNNING, CMD IGNORED: " + command);
         return;
     }
 
@@ -718,9 +725,7 @@ void GdbEngine::sendCommand(const QString &command, int type,
 
     m_cookieForToken[currentToken()] = cmd;
 
-    //qDebug() << "";
     if (!command.isEmpty()) {
-        //qDebug() << qPrintable(currentTime()) << "RUNNING" << cmd.command;
         m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
         //emit gdbInputAvailable(QString(), "         " +  currentTime());
         //emit gdbInputAvailable(QString(), "[" + currentTime() + "]    " + cmd.command);
@@ -920,8 +925,8 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
             break;
 
         default:
-            qDebug() << "FIXME: GdbEngine::handleResult: "
-                "should not happen" << type;
+            debugMessage(QString("FIXME: GdbEngine::handleResult: "
+                "should not happen %1").arg(type));
             break;
     }
 }
@@ -930,7 +935,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
 {
     //createGdbProcessIfNeeded();
     if (m_gdbProc.state() == QProcess::NotRunning) {
-        qDebug() << "NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: " << command;
+        debugMessage("NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: " + command);
         return;
     }
 
@@ -938,11 +943,6 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
     cmd.command = command;
     cmd.type = -1;
 
-    //m_cookieForToken[currentToken()] = cmd;
-    //++currentToken();
-
-    //qDebug() << "";
-    //qDebug() << currentTime() << "Running command:   " << cmd.command;
     emit gdbInputAvailable(QString(), cmd.command);
     m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
 }
@@ -969,7 +969,7 @@ void GdbEngine::handleQueryPwd(const GdbResultRecord &record)
         m_pwd = record.data.findChild("consolestreamoutput").data();
         m_pwd = m_pwd.trimmed();
 #endif
-        //qDebug() << "PWD RESULT:" <<  m_pwd;
+        debugMessage("PWD RESULT: " + m_pwd);
     }
 }
 
@@ -1146,8 +1146,8 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     QString msg = data.findChild("consolestreamoutput").data();
     if (msg.contains("Stopped due to shared library event") || reason.isEmpty()) {
         if (qq->wantsSelectedPluginBreakpoints()) {
-            qDebug() << "SHARED LIBRARY EVENT " << data.toString();
-            qDebug() << "PATTERN" << qq->selectedPluginBreakpointsPattern();
+            debugMessage("SHARED LIBRARY EVENT: " + data.toString());
+            debugMessage("PATTERN: " + qq->selectedPluginBreakpointsPattern());
             sendCommand("sharedlibrary " + qq->selectedPluginBreakpointsPattern());
             continueInferior();
             q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
@@ -1182,6 +1182,8 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
                 + data.findChild("signal-name").toString();
         }
         q->showStatusMessage(msg);
+        // FIXME: shouldn't this use a statis change?
+        debugMessage("CALLING PARENT EXITDEBUGGER");
         q->exitDebugger();
         return;
     }
@@ -1193,21 +1195,21 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     if (qq->skipKnownFrames()) {
         if (reason == "end-stepping-range" || reason == "function-finished") {
             GdbMi frame = data.findChild("frame");
-            //qDebug() << frame.toString();
+            //debugMessage(frame.toString());
             m_currentFrame = frame.findChild("addr").data() + '%' +
                  frame.findChild("func").data() + '%';
 
             QString funcName = frame.findChild("func").data();
             QString fileName = frame.findChild("file").data();
             if (isLeavableFunction(funcName, fileName)) {
-                //qDebug() << "LEAVING" << funcName;
+                //debugMessage("LEAVING" + funcName);
                 ++stepCounter;
                 q->stepOutExec();
                 //stepExec();
                 return;
             }
             if (isSkippableFunction(funcName, fileName)) {
-                //qDebug() << "SKIPPING" << funcName;
+                //debugMessage("SKIPPING" + funcName);
                 ++stepCounter;
                 q->stepExec();
                 return;
@@ -1227,7 +1229,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
         if (reason == "breakpoint-hit") {
             q->showStatusMessage(tr("Stopped at breakpoint"));
             GdbMi frame = data.findChild("frame");
-            //qDebug() << "HIT BREAKPOINT: " << frame.toString();
+            //debugMessage("HIT BREAKPOINT: " + frame.toString());
             m_currentFrame = frame.findChild("addr").data() + '%' +
                  frame.findChild("func").data() + '%';
 
@@ -1243,7 +1245,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
         return;
     }
 
-    qDebug() << "STOPPED FOR UNKNOWN REASON" << data.toString();
+    debugMessage("STOPPED FOR UNKNOWN REASON: " + data.toString());
     // Ignore it. Will be handled with full response later in the
     // JumpToLine or RunToFunction handlers
 #if 1
@@ -1310,7 +1312,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
         QString msg = response.data.findChild("consolestreamoutput").data();
         QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)(\\.(\\d+))?");
         if (supported.indexIn(msg) == -1) {
-            qDebug() << "UNSUPPORTED GDB VERSION " << msg;
+            debugMessage("UNSUPPORTED GDB VERSION " + msg);
             QStringList list = msg.split("\n");
             while (list.size() > 2)
                 list.removeLast();
@@ -1331,7 +1333,7 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
             m_gdbVersion = 10000 * supported.cap(2).toInt()
                          +   100 * supported.cap(3).toInt()
                          +     1 * supported.cap(5).toInt();
-            //qDebug() << "GDB VERSION " << m_gdbVersion;
+            //debugMessage(QString("GDB VERSION: %1").arg(m_gdbVersion));
         }
     }
 }
@@ -1387,7 +1389,7 @@ QString GdbEngine::fullName(const QString &fileName)
     if (fileName.isEmpty())
         return QString();
     QString full = m_shortToFullName.value(fileName, QString());
-    //qDebug() << "RESOLVING: " << fileName << full;
+    //debugMessage("RESOLVING: " + fileName + " " +  full);
     if (!full.isEmpty())
         return full;
     QFileInfo fi(fileName);
@@ -1397,7 +1399,7 @@ QString GdbEngine::fullName(const QString &fileName)
     #ifdef Q_OS_WIN
     full = QDir::cleanPath(full);
     #endif
-    //qDebug() << "STORING: " << fileName << full;
+    //debugMessage("STORING: " + fileName + " " + full);
     m_shortToFullName[fileName] = full;
     m_fullToShortName[full] = fileName;
     return full;
@@ -1425,22 +1427,29 @@ void GdbEngine::shutdown()
 
 void GdbEngine::exitDebugger()
 {
-    //qDebug() << "EXITING: " << m_gdbProc.state();
-    if (m_gdbProc.state() == QProcess::Starting)
+    debugMessage(QString("GDBENGINE EXITDEBUFFER: %1").arg(m_gdbProc.state()));
+    if (m_gdbProc.state() == QProcess::Starting) {
+        debugMessage(QString("WAITING FOR GDB STARTUP TO SHUTDOWN: %1")
+            .arg(m_gdbProc.state()));
         m_gdbProc.waitForStarted();
+    }
     if (m_gdbProc.state() == QProcess::Running) {
+        debugMessage(QString("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
+            .arg(m_gdbProc.state()));
         interruptInferior();
         sendCommand("kill");
         sendCommand("-gdb-exit");
         // 20s can easily happen when loading webkit debug information
         m_gdbProc.waitForFinished(20000);
         if (m_gdbProc.state() != QProcess::Running) {
+            debugMessage(QString("FORCING TERMINATION: %1")
+                .arg(m_gdbProc.state()));
             m_gdbProc.terminate();
             m_gdbProc.waitForFinished(20000);
         }
     }
     if (m_gdbProc.state() != QProcess::NotRunning)
-        qDebug() << "PROBLEM STOPPING DEBUGGER";
+        debugMessage("PROBLEM STOPPING DEBUGGER");
 
     m_outputCollector.shutdown();
     initializeVariables();
@@ -1462,7 +1471,7 @@ bool GdbEngine::startDebugger()
     QString fileName = '"' + fi.absoluteFilePath() + '"';
 
     if (m_gdbProc.state() != QProcess::NotRunning) {
-        qDebug() << "GDB IS ALREADY RUNNING!";
+        debugMessage("GDB IS ALREADY RUNNING!");
         return false;
     }
 
@@ -1636,16 +1645,16 @@ void GdbEngine::handleStart(const GdbResultRecord &response)
         QString msg = response.data.findChild("consolestreamoutput").data();
         QRegExp needle("0x([0-9a-f]+) <" + startSymbolName() + "\\+.*>:");
         if (needle.indexIn(msg) != -1) {
-            //qDebug() << "STREAM: " << msg << needle.cap(1);
+            //debugMessage("STREAM: " + msg + " " + needle.cap(1));
             sendCommand("tbreak *0x" + needle.cap(1));
             m_waitingForFirstBreakpointToBeHit = true;
             sendCommand("-exec-run");
             qq->notifyInferiorRunningRequested();
         } else {
-            qDebug() << "PARSING START ADDRESS FAILED" << msg;
+            debugMessage("PARSING START ADDRESS FAILED: " + msg);
         }
     } else if (response.resultClass == GdbResultError) {
-            qDebug() << "PARSING START ADDRESS FAILED" << response.toString();
+        debugMessage("PARSING START ADDRESS FAILED: " + response.toString());
     }
 }
 
@@ -1740,12 +1749,12 @@ void GdbEngine::setTokenBarrier()
 void GdbEngine::setDebugDumpers(bool on)
 {
     if (on) {
-        qDebug() << "SWITCHING ON DUMPER DEBUGGING";
+        debugMessage("SWITCHING ON DUMPER DEBUGGING");
         sendCommand("set unwindonsignal off");
         q->breakByFunction("qDumpObjectData440");
         //updateLocals();
     } else {
-        qDebug() << "SWITCHING OFF DUMPER DEBUGGING";
+        debugMessage("SWITCHING OFF DUMPER DEBUGGING");
         sendCommand("set unwindonsignal on");
     }
 }
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 0d710e359cf7139c7f45e3d98448a7fa9090d8c9..ee5de645c3de8a1af53b7efa8773153cded0ce7c 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -193,6 +193,7 @@ private:
     void handleShowVersion(const GdbResultRecord &response);
     void handleQueryPwd(const GdbResultRecord &response);
     void handleQuerySources(const GdbResultRecord &response);
+    void debugMessage(const QString &msg);
 
     OutputCollector m_outputCollector;
     QTextCodec *m_outputCodec;