diff --git a/src/app/main.cpp b/src/app/main.cpp
index 9ed1cf10ddaddc103358f27583713cbc412288dc..f4d17c4bf43d9c231cb4a27c4e5ed29ebe9f7357 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -134,40 +134,6 @@ static inline QString msgSendArgumentFailed()
     return QCoreApplication::translate("Application", "Unable to send command line arguments to the already running instance. It appears to be not responding.");
 }
 
-// Prepare a remote argument: If it is a relative file, add the current directory
-// since the the central instance might be running in a different directory.
-
-static inline QString prepareRemoteArgument(const QString &a)
-{
-    QFileInfo fi(a);
-    if (!fi.exists())
-        return a;
-    if (fi.isRelative())
-        return fi.absoluteFilePath();
-    return a;
-}
-
-// Send the arguments to an already running instance of Qt Creator
-static bool sendArguments(SharedTools::QtSingleApplication &app, const QStringList &arguments)
-{
-    if (!arguments.empty()) {
-        // Send off arguments
-        const QStringList::const_iterator acend = arguments.constEnd();
-        for (QStringList::const_iterator it = arguments.constBegin(); it != acend; ++it) {
-            if (!app.sendMessage(prepareRemoteArgument(*it))) {
-                displayError(msgSendArgumentFailed());
-                return false;
-            }
-        }
-    }
-    // Special empty argument means: Show and raise (the slot just needs to be triggered)
-    if (!app.sendMessage(QString())) {
-        displayError(msgSendArgumentFailed());
-        return false;
-    }
-    return true;
-}
-
 static inline QStringList getPluginPaths()
 {
     QStringList rc;
@@ -287,8 +253,13 @@ int main(int argc, char **argv)
     }
 
     const bool isFirstInstance = !app.isRunning();
-    if (!isFirstInstance && foundAppOptions.contains(QLatin1String(CLIENT_OPTION)))
-        return sendArguments(app, pluginManager.arguments()) ? 0 : -1;
+    if (!isFirstInstance && foundAppOptions.contains(QLatin1String(CLIENT_OPTION))) {
+        if (!app.sendMessage(pluginManager.serializedArguments())) {
+            displayError(msgSendArgumentFailed());
+            return -1;
+        }
+        return 0;
+    }
 
     pluginManager.loadPlugins();
     if (coreplugin->hasError()) {
@@ -311,9 +282,10 @@ int main(int argc, char **argv)
         // Silently fallback to unconnected instances for any subsequent
         // instances.
         app.initialize();
-        QObject::connect(&app, SIGNAL(messageReceived(QString)), coreplugin->plugin(), SLOT(remoteArgument(QString)));
+        QObject::connect(&app, SIGNAL(messageReceived(QString)),
+                         &pluginManager, SLOT(remoteArguments(QString)));
     }
-    QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(), SLOT(remoteArgument(QString)));
+    QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(), SLOT(fileOpenRequest(QString)));
 
     // Do this after the event loop has started
     QTimer::singleShot(100, &pluginManager, SLOT(startTests()));
diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h
index e546b72db8bd5ba32ce11ca27b9db28f2dde3637..39bd3671eee5e77ce70fc7569d5fc78ec038f003 100644
--- a/src/libs/extensionsystem/iplugin.h
+++ b/src/libs/extensionsystem/iplugin.h
@@ -55,6 +55,7 @@ public:
     virtual bool initialize(const QStringList &arguments, QString *errorString) = 0;
     virtual void extensionsInitialized() = 0;
     virtual void shutdown() { }
+    virtual void remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { }
 
     PluginSpec *pluginSpec() const;
 
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 8cf365b67041cb2223a11bc9e823912390e7c7d3..6d2be40413b97218b8c54038c25510bb30600a75 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -320,6 +320,91 @@ QList<PluginSpec *> PluginManager::plugins() const
     return d->pluginSpecs;
 }
 
+/*!
+    \fn QString PluginManager::serializedArguments() const
+
+    Serialize plugin options and arguments for sending in a single string
+    via QtSingleApplication:
+    ":myplugin|-option1|-option2|:arguments|argument1|argument2",
+    as a list of lists started by a keyword with a colon. Arguments are last.
+
+    \sa setPluginPaths()
+*/
+
+static const char argumentKeywordC[] = ":arguments";
+
+QString PluginManager::serializedArguments() const
+{
+    const QChar separator = QLatin1Char('|');
+    QString rc;
+    foreach (const PluginSpec *ps, plugins()) {
+        if (!ps->arguments().isEmpty()) {
+            if (!rc.isEmpty())
+                rc += separator;
+            rc += QLatin1Char(':');
+            rc += ps->name();
+            rc += separator;
+            rc +=  ps->arguments().join(QString(separator));
+        }
+    }
+    if (!d->arguments.isEmpty()) {
+        if (!rc.isEmpty())
+            rc += separator;
+        rc += QLatin1String(argumentKeywordC);
+        // If the argument appears to be a file, make it absolute
+        // when sending to another instance.
+        foreach(const QString &argument, d->arguments) {
+            rc += separator;
+            const QFileInfo fi(argument);
+            if (fi.exists() && fi.isRelative()) {
+                rc += fi.absoluteFilePath();
+            } else {
+                rc += argument;
+            }
+        }
+    }
+    return rc;
+}
+
+/* Extract a sublist from the serialized arguments
+ * indicated by a keyword starting with a colon indicator:
+ * ":a,i1,i2,:b:i3,i4" with ":a" -> "i1,i2"
+ */
+static QStringList subList(const QStringList &in, const QString &key)
+{
+    QStringList rc;
+    // Find keyword and copy arguments until end or next keyword
+    const QStringList::const_iterator inEnd = in.constEnd();
+    QStringList::const_iterator it = qFind(in.constBegin(), inEnd, key);
+    if (it != inEnd) {
+        const QChar nextIndicator = QLatin1Char(':');
+        for (++it; it != inEnd && !it->startsWith(nextIndicator); ++it)
+            rc.append(*it);
+    }
+    return rc;
+}
+
+/*!
+    \fn PluginManager::remoteArguments(const QString &argument)
+
+    Parses the options encoded by serializedArguments() const
+    and passes them on to the respective plugins along with the arguments.
+*/
+
+void PluginManager::remoteArguments(const QString &serializedArgument)
+{
+    if (serializedArgument.isEmpty())
+        return;
+    QStringList serializedArguments = serializedArgument.split(QLatin1Char('|'));
+    const QStringList arguments = subList(serializedArguments, QLatin1String(argumentKeywordC));
+    foreach (const PluginSpec *ps, plugins()) {
+        if (ps->state() == PluginSpec::Running) {
+            const QStringList pluginOptions = subList(serializedArguments, QLatin1Char(':') + ps->name());
+            ps->plugin()->remoteCommand(pluginOptions, arguments);
+        }
+    }
+}
+
 /*!
     \fn bool PluginManager::parseOptions(const QStringList &args, const QMap<QString, bool> &appOptions, QMap<QString, QString> *foundAppOptions, QString *errorString)
     Takes the list of command line options in \a args and parses them.
diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h
index 79c0b683564b0547cbf8b296208281351a13ade8..f4140da9d14624413ba48b1a62f7ba859a04a6c0 100644
--- a/src/libs/extensionsystem/pluginmanager.h
+++ b/src/libs/extensionsystem/pluginmanager.h
@@ -108,6 +108,8 @@ public:
     void formatPluginOptions(QTextStream &str, int optionIndentation, int descriptionIndentation) const;
     void formatPluginVersions(QTextStream &str) const;
 
+    QString serializedArguments() const;
+
     bool runningTests() const;
     QString testDataDirectory() const;
 
@@ -116,6 +118,10 @@ signals:
     void aboutToRemoveObject(QObject *obj);
 
     void pluginsChanged();
+
+public slots:
+    void remoteArguments(const QString &serializedArguments);
+
 private slots:
     void startTests();
 
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index da2825ecf84c11dc2aa42da4bbeca0e58b41c3eb..8b9317fb65131c06125586a9597cdec9064e4f76 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -87,16 +87,15 @@ void CorePlugin::extensionsInitialized()
     m_mainWindow->extensionsInitialized();
 }
 
-void CorePlugin::remoteArgument(const QString& arg)
+void CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args)
 {
-    // An empty argument is sent to trigger activation
-    // of the window via QtSingleApplication. It should be
-    // the last of a sequence.
-    if (arg.isEmpty()) {
-        m_mainWindow->activateWindow();
-    } else {
-        m_mainWindow->openFiles(QStringList(arg));
-    }
+    m_mainWindow->openFiles(args);
+    m_mainWindow->activateWindow();
+}
+
+void CorePlugin::fileOpenRequest(const QString &f)
+{
+    remoteCommand(QStringList(), QStringList(f));
 }
 
 void CorePlugin::shutdown()
diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h
index 58e5958cc85ef5eb97793ae4ba734106bf72de7c..3c03c7b836c72d0f38a9c4d35bc5c8d4e3ade616 100644
--- a/src/plugins/coreplugin/coreplugin.h
+++ b/src/plugins/coreplugin/coreplugin.h
@@ -49,9 +49,10 @@ public:
     virtual bool initialize(const QStringList &arguments, QString *errorMessage = 0);
     virtual void extensionsInitialized();
     virtual void shutdown();
+    virtual void remoteCommand(const QStringList & /* options */, const QStringList &args);
 
 public slots:
-    void remoteArgument(const QString&);
+    void fileOpenRequest(const QString&);
 
 private:
     void parseArguments(const QStringList & arguments);
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index b538b7fe67578706753db8da04fe9736c42b154f..333a84dfc9405df3059bd5b39ad1748c4cf1092f 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -812,8 +812,14 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6
         if (!crashParameter.isEmpty()) {
             ULONG64 evtNr = crashParameter.toULongLong();
             const HRESULT hr = m_cif.debugControl->SetNotifyEventHandle(evtNr);
-            if (FAILED(hr))
+            // Unless QtCreator is spawned by the debugger and inherits the handles,
+            // the event handling does not work reliably
+            // (that is, the crash event is not delivered).
+            if (SUCCEEDED(hr)) {
+                QTimer::singleShot(0, m_engine, SLOT(slotBreakAttachToCrashed()));
+            } else {
                 m_engine->warning(QString::fromLatin1("Handshake failed on event #%1: %2").arg(evtNr).arg(msgComFailed("SetNotifyEventHandle", hr)));
+            }
         }
     }
     m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
@@ -1234,6 +1240,17 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage)
     return true;
 }
 
+void CdbDebugEngine::slotBreakAttachToCrashed()
+{
+    // Force a break when attaching to crashed process (if Creator was not spawned
+    // from handler).
+    if (state() != InferiorStopped) {
+        manager()->showDebuggerOutput(LogMisc, QLatin1String("Forcing break..."));
+        m_d->m_dumper->disable();
+        interruptInferior();
+    }
+}
+
 void CdbDebugEngine::interruptInferior()
 {
     if (!m_d->m_hDebuggeeProcess || !m_d->isDebuggeeRunning())
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 077faf4e14fe1d2b6085af2c373971dfab106416..59d7658a925c5a3d3791ab961e18ba9cfefcd16c 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -111,6 +111,7 @@ private slots:
     void slotConsoleStubStarted();
     void slotConsoleStubError(const QString &msg);
     void slotConsoleStubTerminated();    
+    void slotBreakAttachToCrashed();
     void warning(const QString &w);
 
 private:
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 1e91222a06b545fddb73668e0c0694139fd70656..e1b938815c1c3291787429bfe88cefe64146bac0 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -505,14 +505,19 @@ bool DebuggingHelperOptionPage::matches(const QString &s) const
 //
 ///////////////////////////////////////////////////////////////////////
 
+
+DebuggerPlugin::AttachRemoteParameters::AttachRemoteParameters() :
+    attachPid(0),
+    winCrashEvent(0)
+{
+}
+
 DebuggerPlugin::DebuggerPlugin()
   : m_manager(0),
     m_debugMode(0),
     m_locationMark(0),
     m_gdbRunningContext(0),
     m_cmdLineEnabledEngines(AllEngineTypes),
-    m_cmdLineAttachPid(0),
-    m_cmdLineWinCrashEvent(0),
     m_toggleLockedAction(0)
 {}
 
@@ -555,9 +560,10 @@ static QString msgInvalidNumericParameter(const QString &a, const QString &numbe
 }
 
 // Parse arguments
-bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it,
-                                   const QStringList::const_iterator &cend,
-                                   QString *errorMessage)
+static bool parseArgument(QStringList::const_iterator &it,
+                          const QStringList::const_iterator &cend,
+                          DebuggerPlugin::AttachRemoteParameters *attachRemoteParameters,
+                          unsigned *enabledEngines, QString *errorMessage)
 {
     const QString &option = *it;
     // '-debug <pid>'
@@ -568,10 +574,10 @@ bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it,
             return false;
         }
         bool ok;
-        m_cmdLineAttachPid = it->toULongLong(&ok);
+        attachRemoteParameters->attachPid = it->toULongLong(&ok);
         if (!ok) {
-            m_cmdLineAttachPid = 0;
-            m_cmdLineAttachCore = *it;
+            attachRemoteParameters->attachPid = 0;
+            attachRemoteParameters->attachCore = *it;
         }
         return true;
     }
@@ -584,7 +590,7 @@ bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it,
             return false;
         }
         bool ok;
-        m_cmdLineWinCrashEvent = it->toULongLong(&ok);
+        attachRemoteParameters->winCrashEvent = it->toULongLong(&ok);
         if (!ok) {
             *errorMessage = msgInvalidNumericParameter(option, *it);
             return false;
@@ -593,40 +599,55 @@ bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it,
     }
     // engine disabling
     if (option == QLatin1String("-disable-cdb")) {
-        m_cmdLineEnabledEngines &= ~CdbEngineType;
+        *enabledEngines &= ~Debugger::CdbEngineType;
         return true;
     }
     if (option == QLatin1String("-disable-gdb")) {
-        m_cmdLineEnabledEngines &= ~GdbEngineType;
+        *enabledEngines &= ~Debugger::GdbEngineType;
         return true;
     }
     if (option == QLatin1String("-disable-sdb")) {
-        m_cmdLineEnabledEngines &= ~ScriptEngineType;
+        *enabledEngines &= ~Debugger::ScriptEngineType;
         return true;
     }
 
-    *errorMessage = tr("Invalid debugger option: %1").arg(option);
+    *errorMessage = DebuggerPlugin::tr("Invalid debugger option: %1").arg(option);
     return false;
 }
 
-bool DebuggerPlugin::parseArguments(const QStringList &args, QString *errorMessage)
+static bool parseArguments(const QStringList &args,
+                           DebuggerPlugin::AttachRemoteParameters *attachRemoteParameters,
+                           unsigned *enabledEngines, QString *errorMessage)
 {
     const QStringList::const_iterator cend = args.constEnd();
     for (QStringList::const_iterator it = args.constBegin(); it != cend; ++it)
-        if (!parseArgument(it, cend, errorMessage))
+        if (!parseArgument(it, cend, attachRemoteParameters, enabledEngines, errorMessage))
             return false;
     if (Debugger::Constants::Internal::debug)
         qDebug().nospace() << args << "engines=0x"
-            << QString::number(m_cmdLineEnabledEngines, 16)
-            << " pid" << m_cmdLineAttachPid
-            << " core" << m_cmdLineAttachCore << '\n';
+            << QString::number(*enabledEngines, 16)
+            << " pid" << attachRemoteParameters->attachPid
+            << " core" << attachRemoteParameters->attachCore << '\n';
     return true;
 }
 
+void DebuggerPlugin::remoteCommand(const QStringList &options, const QStringList &)
+{
+    QString errorMessage;
+    AttachRemoteParameters parameters;
+    unsigned dummy = 0;
+    // Did we receive a request for debugging (unless it is ourselves)?
+    if (parseArguments(options, &parameters, &dummy, &errorMessage)
+        && parameters.attachPid != quint64(QCoreApplication::applicationPid())) {
+        m_attachRemoteParameters = parameters;
+        attachCmdLine();
+    }
+}
+
 bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMessage)
 {
     // Do not fail the whole plugin if something goes wrong here
-    if (!parseArguments(arguments, errorMessage)) {
+    if (!parseArguments(arguments, &m_attachRemoteParameters, &m_cmdLineEnabledEngines, errorMessage)) {
         *errorMessage = tr("Error evaluating command line arguments: %1")
             .arg(*errorMessage);
         qWarning("%s\n", qPrintable(*errorMessage));
@@ -1000,18 +1021,25 @@ void DebuggerPlugin::extensionsInitialized()
     //qDebug() << "EXTENSIONS INITIALIZED:" << env;
     if (!env.isEmpty())
         m_manager->runTest(QString::fromLocal8Bit(env));
-    if (m_cmdLineAttachPid)
-        QTimer::singleShot(0, this, SLOT(attachCmdLinePid()));
-    if (!m_cmdLineAttachCore.isEmpty())
-        QTimer::singleShot(0, this, SLOT(attachCmdLineCore()));
+    if (m_attachRemoteParameters.attachPid || !m_attachRemoteParameters.attachCore.isEmpty())
+        QTimer::singleShot(0, this, SLOT(attachCmdLine()));
 }
 
-void DebuggerPlugin::attachCmdLinePid()
+void DebuggerPlugin::attachCmdLine()
 {
-    m_manager->showStatusMessage(tr("Attaching to PID %1.").arg(m_cmdLineAttachPid));
-    const QString crashParameter =
-        m_cmdLineWinCrashEvent ? QString::number(m_cmdLineWinCrashEvent) : QString();
-    attachExternalApplication(m_cmdLineAttachPid, crashParameter);
+    if (m_manager->state() != DebuggerNotReady)
+        return;
+    if (m_attachRemoteParameters.attachPid) {
+        m_manager->showStatusMessage(tr("Attaching to PID %1.").arg(m_attachRemoteParameters.attachPid));
+        const QString crashParameter =
+                m_attachRemoteParameters.winCrashEvent ? QString::number(m_attachRemoteParameters.winCrashEvent) : QString();
+        attachExternalApplication(m_attachRemoteParameters.attachPid, crashParameter);
+        return;
+    }
+    if (!m_attachRemoteParameters.attachCore.isEmpty()) {
+        m_manager->showStatusMessage(tr("Attaching to core %1.").arg(m_attachRemoteParameters.attachCore));
+        attachCore(m_attachRemoteParameters.attachCore, QString());
+    }
 }
 
 /*! Activates the previous mode when the current mode is the debug mode. */
@@ -1326,12 +1354,6 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP
         ProjectExplorerPlugin::instance()->startRunControl(runControl, ProjectExplorer::Constants::DEBUGMODE);
 }
 
-void DebuggerPlugin::attachCmdLineCore()
-{
-    m_manager->showStatusMessage(tr("Attaching to core %1.").arg(m_cmdLineAttachCore));
-    attachCore(m_cmdLineAttachCore, QString());
-}
-
 void DebuggerPlugin::attachCore()
 {
     AttachCoreDialog dlg(m_manager->mainWindow());
diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h
index 1e1af9cb8f7419e094e1451360876bd8f35d5bef..db064b20b2a2a56cc7cac3943f9dad7f70b59b31 100644
--- a/src/plugins/debugger/debuggerplugin.h
+++ b/src/plugins/debugger/debuggerplugin.h
@@ -36,7 +36,6 @@
 #include <QtCore/QStringList>
 
 QT_BEGIN_NAMESPACE
-class QAbstractItemView;
 class QAction;
 class QCursor;
 class QMenu;
@@ -68,6 +67,15 @@ class DebuggerPlugin : public ExtensionSystem::IPlugin
     Q_OBJECT
 
 public:
+    struct AttachRemoteParameters {
+        AttachRemoteParameters();
+
+        quint64 attachPid;
+        QString attachCore;
+        // Event handle for attaching to crashed Windows processes.
+        quint64 winCrashEvent;
+    };
+
     DebuggerPlugin();
     ~DebuggerPlugin();
 
@@ -75,6 +83,7 @@ private:
     virtual bool initialize(const QStringList &arguments, QString *error_message);
     virtual void shutdown();
     virtual void extensionsInitialized();
+    virtual void remoteCommand(const QStringList &options, const QStringList &arguments);
 
     QVariant configValue(const QString &name) const;
 
@@ -106,16 +115,11 @@ private slots:
     void startRemoteApplication();
     void attachExternalApplication();
     void attachCore();
-    void attachCmdLinePid();
-    void attachCmdLineCore();
+    void attachCmdLine();
 
 private:
     void readSettings();
     void writeSettings() const;
-    bool parseArguments(const QStringList &args, QString *errorMessage);
-    inline bool parseArgument(QStringList::const_iterator &it,
-                              const QStringList::const_iterator& end,
-                              QString *errorMessage);
     void attachExternalApplication(qint64 pid, const QString &crashParameter = QString());
     void attachCore(const QString &core, const QString &exeFileName);
 
@@ -131,11 +135,9 @@ private:
     QString m_previousMode;
     TextEditor::BaseTextMark *m_locationMark;
     int m_gdbRunningContext;
+    AttachRemoteParameters m_attachRemoteParameters;
     unsigned m_cmdLineEnabledEngines;
-    quint64 m_cmdLineAttachPid;
-    QString m_cmdLineAttachCore;
-    // Event handle for attaching to crashed Windows processes.
-    quint64 m_cmdLineWinCrashEvent;
+
     QAction *m_toggleLockedAction;
 
     QAction *m_startExternalAction;
diff --git a/src/tools/qtcdebugger/main.cpp b/src/tools/qtcdebugger/main.cpp
index 8be595a0ce1201e1e30a6a9994056289fcc67cff..616fc82727db75e11830feac7212b43d890c428d 100644
--- a/src/tools/qtcdebugger/main.cpp
+++ b/src/tools/qtcdebugger/main.cpp
@@ -41,6 +41,7 @@
 #include <QtCore/QByteArray>
 #include <QtCore/QString>
 #include <QtCore/QDir>
+#include <QtCore/QTime>
 #include <QtCore/QProcess>
 #include <QtGui/QPushButton>
 
@@ -61,6 +62,7 @@ static const WCHAR *debuggerRegistryValueNameC = L"Debugger";
 static const WCHAR *debuggerRegistryDefaultValueNameC = L"Debugger.Default";
 
 static const char *linkC = "http://msdn.microsoft.com/en-us/library/cc266343.aspx";
+static const char *creatorBinaryC = "qtcreator.exe";
 
 static inline QString wCharToQString(const WCHAR *w) { return QString::fromUtf16(reinterpret_cast<const ushort *>(w)); }
 #ifdef __GNUC__
@@ -343,23 +345,49 @@ static QString getProcessBaseName(DWORD pid)
 
 // ------- main modes
 
-bool startCreatorAsDebugger(QString *errorMessage)
+static bool waitForProcess(DWORD pid)
+{
+    HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION|READ_CONTROL|SYNCHRONIZE, false, pid);
+    if (handle == NULL)
+        return false;
+    const DWORD waitResult = WaitForSingleObject(handle, INFINITE);
+    CloseHandle(handle);
+    return waitResult == WAIT_OBJECT_0;
+}
+
+bool startCreatorAsDebugger(bool asClient, QString *errorMessage)
 {
     const QString dir = QApplication::applicationDirPath();
-    const QString binary = dir + QLatin1String("/qtcreator.exe");
+    const QString binary = dir + QLatin1Char('/') + QLatin1String(creatorBinaryC);
     QStringList args;
+    if (asClient)
+        args << QLatin1String("-client");
     args << QLatin1String("-debug") << QString::number(argProcessId)
             << QLatin1String("-wincrashevent") << QString::number(argWinCrashEvent);
     if (debug)
         qDebug() << binary << args;
     QProcess p;
     p.setWorkingDirectory(dir);
+    QTime executionTime;
+    executionTime.start();
     p.start(binary, args, QIODevice::NotOpen);
     if (!p.waitForStarted()) {
         *errorMessage = QString::fromLatin1("Unable to start %1!").arg(binary);
         return false;
     }
-    p.waitForFinished(-1);
+    // Short execution time: indicates that -client was passed on attach to
+    // another running instance of Qt Creator. Keep alive as long as user
+    // does not close the process. If that fails, try to launch 2nd instance.
+    const bool waitResult = p.waitForFinished(-1);
+    const bool ranAsClient = asClient && (executionTime.elapsed() < 10000);
+    if (waitResult && p.exitStatus() == QProcess::NormalExit && ranAsClient) {
+        if (p.exitCode() == 0) {
+            waitForProcess(argProcessId);
+        } else {
+            errorMessage->clear();
+            return startCreatorAsDebugger(false, errorMessage);
+        }
+    }
     return true;
 }
 
@@ -408,7 +436,8 @@ bool startDefaultDebugger(QString *errorMessage)
 bool chooseDebugger(QString *errorMessage)
 {
     QString defaultDebugger;
-    const QString msg = QString::fromLatin1("The application \"%1\" (process id %2)  crashed. Would you like to debug it?").arg(getProcessBaseName(argProcessId)).arg(argProcessId);
+    const QString processName = getProcessBaseName(argProcessId);
+    const QString msg = QString::fromLatin1("The application \"%1\" (process id %2)  crashed. Would you like to debug it?").arg(processName).arg(argProcessId);
     QMessageBox msgBox(QMessageBox::Information, QLatin1String(titleC), msg, QMessageBox::Cancel);
     QPushButton *creatorButton = msgBox.addButton(QLatin1String("Debug with Qt Creator"), QMessageBox::AcceptRole);
     QPushButton *defaultButton = msgBox.addButton(QLatin1String("Debug with default debugger"), QMessageBox::AcceptRole);
@@ -416,8 +445,10 @@ bool chooseDebugger(QString *errorMessage)
                               && !defaultDebugger.isEmpty());
     msgBox.exec();
     if (msgBox.clickedButton() == creatorButton) {
-        // Just in case, default to standard
-        if (startCreatorAsDebugger(errorMessage))
+        // Just in case, default to standard. Do not run as client in the unlikely case
+        // Creator crashed
+        const bool canRunAsClient = !processName.contains(QLatin1String(creatorBinaryC), Qt::CaseInsensitive);
+        if (startCreatorAsDebugger(canRunAsClient, errorMessage))
             return true;
         return startDefaultDebugger(errorMessage);
     }
@@ -552,7 +583,7 @@ int main(int argc, char *argv[])
         usage(QCoreApplication::applicationFilePath(), errorMessage);
         break;
     case ForceCreatorMode:
-        ex = startCreatorAsDebugger(&errorMessage) ? 0 : -1;
+        ex = startCreatorAsDebugger(true, &errorMessage) ? 0 : -1;
         break;
     case ForceDefaultMode:
         ex = startDefaultDebugger(&errorMessage) ? 0 : -1;