diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 199a6f52180bf86e27a220de63aab38115d20ced..dedee2a22dec33822f9c96902c9edebb5e6d3a41 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "debuggerdialogs.h"
+#include "debuggerconstants.h"
 
 #include "ui_attachcoredialog.h"
 #include "ui_attachexternaldialog.h"
@@ -39,6 +40,8 @@
 #  include "shared/dbgwinutils.h"
 #endif
 
+#include <coreplugin/icore.h>
+
 #include <QtCore/QDebug>
 #include <QtCore/QDir>
 #include <QtCore/QFile>
@@ -49,7 +52,7 @@
 #include <QtGui/QPushButton>
 #include <QtGui/QProxyModel>
 #include <QtGui/QSortFilterProxyModel>
-
+#include <QtGui/QMessageBox>
 
 namespace Debugger {
 namespace Internal {
@@ -606,5 +609,28 @@ bool AddressDialog::isValid() const
     return ok;
 }
 
+int warningWithSettings(const QString &title,
+                        const QString &text,
+                        const QString &details,
+                        const QString &settingsId,
+                        QWidget *parent)
+{
+    QMessageBox msgBox(QMessageBox::Warning, title, text,
+                       QMessageBox::Ok, parent);
+    if (details.isEmpty())
+        msgBox.setDetailedText(details);
+    QAbstractButton *settingsButton = 0;
+    if (!settingsId.isEmpty())
+        settingsButton = msgBox.addButton(QCoreApplication::translate("Debugger::MessageBox", "Settings..."),
+                                          QMessageBox::AcceptRole);
+    const int dialogCode = msgBox.exec();
+    if (settingsButton && msgBox.clickedButton() == settingsButton) {
+        Core::ICore::instance()->showOptionsDialog(QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY),
+                                                   settingsId);
+        return 2;
+    }
+    return dialogCode;
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index d20f7e7c249cfe23cdc5a3ce8cb8bceef69a98dd..974844e4fdc561958908bd0ef950e7a4eb085804 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -63,6 +63,14 @@ struct ProcData
     QString state;
 };
 
+// Display a warning with an additional button to open
+// the debugger settings dialog if settingsId is nonempty.
+int warningWithSettings(const QString &title,
+                        const QString &text,
+                        const QString &details = QString(),
+                        const QString &settingsId = QString(),
+                        QWidget *parent = 0);
+
 class AttachCoreDialog : public QDialog
 {
     Q_OBJECT
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 660340bb4c433937b333277161f4285d8ffe9c8c..b658dddeea90a4b9a654ac59f6e6635f1a4f8bee 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -1001,17 +1001,9 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp)
     if (!d->m_engine) {
         emit debuggingFinished();
         // Create Message box with possibility to go to settings
-        QAbstractButton *settingsButton = 0;
-        QMessageBox msgBox(QMessageBox::Warning, tr("Warning"),
-            tr("Cannot debug '%1' (tool chain: '%2'): %3").
-            arg(d->m_startParameters->executable, toolChainName, errorMessage),
-            QMessageBox::Ok);
-        if (!settingsIdHint.isEmpty())
-            settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole);
-        msgBox.exec();
-        if (msgBox.clickedButton() == settingsButton)
-            Core::ICore::instance()->showOptionsDialog(
-                _(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint);
+        const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3").
+                            arg(d->m_startParameters->executable, toolChainName, errorMessage);
+        warningWithSettings(tr("Warning"),  msg, QString(), settingsIdHint);
         return;
     }
 
diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h
index e471f4fcd88c3b9e7a35b972ff9379244e2a6f21..53d49770fada2a2fe010395be6848a913e0c8495 100644
--- a/src/plugins/debugger/gdb/abstractgdbadapter.h
+++ b/src/plugins/debugger/gdb/abstractgdbadapter.h
@@ -69,7 +69,7 @@ public:
 
 signals:
     void adapterStarted();
-    void adapterStartFailed(const QString &msg);
+    void adapterStartFailed(const QString &msg, const QString &settingsIdHint);
     void adapterShutDown();
     void adapterShutdownFailed(const QString &msg);
     void adapterCrashed(const QString &msg);
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp
index 6cf129963454b14db491866b0a5ea1d09869644d..0918bf866c0786411642bb800636a7b6cd045cf5 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp
@@ -80,7 +80,7 @@ void AttachGdbAdapter::startAdapter()
 
     if (!m_engine->m_outputCollector.listen()) {
         emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
-                .arg(m_engine->m_outputCollector.errorString()));
+                .arg(m_engine->m_outputCollector.errorString()), QString());
         return;
     }
     gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp
index 5fa80055c5e98ad4787aa98ffde27fc217e558db..92edb42e68dc69a84b4e724137614ff11214067b 100644
--- a/src/plugins/debugger/gdb/coregdbadapter.cpp
+++ b/src/plugins/debugger/gdb/coregdbadapter.cpp
@@ -80,7 +80,7 @@ void CoreGdbAdapter::startAdapter()
 
     if (!m_engine->m_outputCollector.listen()) {
         emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
-                .arg(m_engine->m_outputCollector.errorString()));
+                .arg(m_engine->m_outputCollector.errorString()), QString());
         return;
     }
     gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index b92e8e7b548a367435fd87c19706815185cefeea..a45e32086454cd306296133b167974486329269d 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -261,8 +261,8 @@ void GdbEngine::connectAdapter()
 
     connect(m_gdbAdapter, SIGNAL(adapterStarted()),
         this, SLOT(handleAdapterStarted()));
-    connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString)),
-        this, SLOT(handleAdapterStartFailed(QString)));
+    connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)),
+        this, SLOT(handleAdapterStartFailed(QString,QString)));
     connect(m_gdbAdapter, SIGNAL(adapterShutDown()),
         this, SLOT(handleAdapterShutDown()));
     connect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)),
@@ -4051,10 +4051,11 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
 // Starting up & shutting down
 //
 
-void GdbEngine::handleAdapterStartFailed(const QString &msg)
+void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint)
 {
+    setState(AdapterStartFailed);
     debugMessage(_("ADAPTER START FAILED"));
-    showMessageBox(QMessageBox::Critical, tr("Adapter start failed"), msg);
+    warningWithSettings(tr("Adapter start failed"), msg, QString(), settingsIdHint);
     shutdown();
 }
 
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index a3135449f524e886060fa56f02fd39a986a6a337..1bc2d60e4307cdd9a108528697842bf7dcb3b4df 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -238,7 +238,7 @@ private slots:
     void readDebugeeOutput(const QByteArray &data);
 
     void handleAdapterStarted();
-    void handleAdapterStartFailed(const QString &msg);
+    void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString());
 
     void handleInferiorPrepared();
     void handleInferiorPreparationFailed(const QString &msg);
diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp
index a71039a3011016ac56e86a2bd9fcb4e80e18b747..a45787afffb2a3d95be7782000911fed431ab41f 100644
--- a/src/plugins/debugger/gdb/plaingdbadapter.cpp
+++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp
@@ -345,7 +345,7 @@ void PlainGdbAdapter::emitAdapterStartFailed(const QString &msg)
     bool blocked = m_stubProc.blockSignals(true);
     m_stubProc.stop();
     m_stubProc.blockSignals(blocked);
-    emit adapterStartFailed(msg);
+    emit adapterStartFailed(msg, QString());
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index 85c6419c762bcc14058c8ec4e668cace33952eab..86c7e6f52783d18ba6a24768da52f706726f506c 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -29,6 +29,7 @@
 
 #include "trkgdbadapter.h"
 #include "trkoptions.h"
+#include "trkoptionspage.h"
 #include "debuggerstringutils.h"
 #ifndef STANDALONE_RUNNER
 #include "gdbengine.h"
@@ -397,7 +398,7 @@ void TrkGdbAdapter::emitDelayedAdapterStartFailed(const QString &msg)
 
 void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed()
 {
-    emit adapterStartFailed(m_adapterFailMessage);
+    emit adapterStartFailed(m_adapterFailMessage, TrkOptionsPage::settingsId());
 }
 
 void TrkGdbAdapter::startInferiorEarly()
@@ -420,7 +421,7 @@ void TrkGdbAdapter::startInferiorEarly()
             QString msg = _("Failed to connect to %1 after "
                 "%2 attempts").arg(device).arg(m_waitCount);
             logMessage(msg);
-            emit adapterStartFailed(msg);
+            emit adapterStartFailed(msg, TrkOptionsPage::settingsId());
         }
         return;
     }
@@ -1585,16 +1586,28 @@ void TrkGdbAdapter::interruptInferior()
 
 void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error)
 {
-    logMessage(QString("GDB: Process Error %1: %2")
-        .arg(error).arg(m_gdbProc.errorString()));
+    if (error == QProcess::FailedToStart) {
+        const QString msg = QString::fromLatin1("GDB: Cannot start '%1': %2. Please check the settings.").arg(m_options->gdb).arg(m_gdbProc.errorString());
+        emitDelayedAdapterStartFailed(msg); // Emitted from QProcess::start() on Windows
+    } else {
+        // Others should trigger handleGdbFinished
+        const QString msg = QString::fromLatin1("GDB: Process error %1: %2").arg(error).arg(m_gdbProc.errorString());
+        logMessage(msg);
+    }
 }
 
 void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
 {
-    logMessage(QString("GDB: ProcessFinished %1 %2")
-        .arg(exitCode).arg(exitStatus));
-    setState(DebuggerNotReady);
-    emit adapterShutDown();
+    const QString msg = exitStatus == QProcess::NormalExit ?
+                        QString::fromLatin1("GDB: Process finished (exit code: %1).").arg(exitCode) :
+                        QString::fromLatin1("GDB: Process crashed: %1").arg(m_gdbProc.errorString());
+    if (state() == AdapterStarting) {
+        emitDelayedAdapterStartFailed(msg);// Potentially emitted from QProcess::start() on Windows
+    } else {
+        logMessage(msg);
+        setState(DebuggerNotReady);
+        emit adapterShutDown();
+    }
 }
 
 void TrkGdbAdapter::handleGdbStarted()
@@ -1647,7 +1660,7 @@ void TrkGdbAdapter::startAdapter()
                 "listener %1 on %2: %3\n");
             msg = msg.arg(blueToothListener, device, m_rfcommProc.errorString());
             msg += QString::fromLocal8Bit(m_rfcommProc.readAllStandardError());
-            emit adapterStartFailed(msg);
+            emit adapterStartFailed(msg, TrkOptionsPage::settingsId());
             return;
         }
     }
@@ -2070,6 +2083,7 @@ void TrkGdbAdapter::shutdown()
 {
     switch (state()) {
     case AdapterStarting:
+    case AdapterStartFailed:
         cleanup();
         setState(DebuggerNotReady);
         return;