From 36a94b69b12e458a99b12067e8220f541fcdeb39 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Mon, 11 May 2009 16:54:35 +0200
Subject: [PATCH] Added Detaching to CDB.

---
 src/plugins/debugger/cdb/cdbdebugengine.cpp | 108 +++++++++++---------
 src/plugins/debugger/cdb/cdbdebugengine.h   |   1 +
 src/plugins/debugger/cdb/cdbdebugengine_p.h |   3 +
 3 files changed, 65 insertions(+), 47 deletions(-)

diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index a027ae3c3c..789936f3ea 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -615,59 +615,73 @@ void CdbDebugEngine::processTerminated(unsigned long exitCode)
     m_d->m_debuggerManager->exitDebugger();
 }
 
-void CdbDebugEngine::exitDebugger()
+// End debugging using
+void CdbDebugEnginePrivate::endDebugging(EndDebuggingMode em)
 {
+    enum Action { Detach, Terminate };
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO;
+        qDebug() << Q_FUNC_INFO << em;
 
-    if (m_d->m_hDebuggeeProcess) {
-        QString errorMessage;
-        m_d->clearForRun();
-        bool wasRunning = false;
-        // Terminate or detach if we are running
-        HRESULT hr;
-        switch (m_d->m_mode) {
-        case AttachExternal:
-            wasRunning = m_d->isDebuggeeRunning();
-            if (wasRunning) { // Process must be stopped in order to detach
-                m_d->interruptInterferiorProcess(&errorMessage);
-                QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
-            }
-            hr = m_d->m_cif.debugClient->DetachCurrentProcess();
-            if (FAILED(hr))
-                errorMessage += msgComFailed("DetachCurrentProcess", hr);
-            if (debugCDB)
-                qDebug() << Q_FUNC_INFO << "detached" << msgDebugEngineComResult(hr);
-            break;
-        case StartExternal:
-        case StartInternal:
-            wasRunning = m_d->isDebuggeeRunning();
-            if (wasRunning) { // Process must be stopped in order to terminate
-                m_d->interruptInterferiorProcess(&errorMessage);
-                QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
-            }
-            // Terminate and wait for stop events.
-            hr = m_d->m_cif.debugClient->TerminateCurrentProcess();
+    if (m_mode == AttachCore || !m_hDebuggeeProcess)
+        return;
+    // Figure out action
+    Action action;
+    switch (em) {
+    case EndDebuggingAuto:
+        action = m_mode == AttachExternal ? Detach : Terminate;
+        break;
+    case EndDebuggingDetach:
+        action = Detach;
+        break;
+    case EndDebuggingTerminate:
+        action = Terminate;
+        break;
+    }
+    if (debugCDB)
+        qDebug() << Q_FUNC_INFO << action;
+    // Need a stopped debuggee to act
+    QString errorMessage;
+    const bool wasRunning = isDebuggeeRunning();
+    if (wasRunning) { // Process must be stopped in order to terminate
+        interruptInterferiorProcess(&errorMessage);
+        QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+    }    
+    HRESULT hr;
+    switch (action) {
+    case Detach:
+        hr = m_cif.debugClient->DetachCurrentProcess();
+        if (FAILED(hr))
+            errorMessage += msgComFailed("DetachCurrentProcess", hr);
+        break;
+    case Terminate:
+        hr = m_cif.debugClient->TerminateCurrentProcess();
+        if (FAILED(hr))
+            errorMessage += msgComFailed("TerminateCurrentProcess", hr);
+        if (!wasRunning) {
+            hr = m_cif.debugClient->TerminateProcesses();
             if (FAILED(hr))
-                errorMessage += msgComFailed("TerminateCurrentProcess", hr);
-            if (!wasRunning) {
-                hr = m_d->m_cif.debugClient->TerminateProcesses();
-                if (FAILED(hr))
-                    errorMessage += msgComFailed("TerminateProcesses", hr);
-            }
-            QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
-            if (debugCDB)
-                qDebug() << Q_FUNC_INFO << "terminated" << msgDebugEngineComResult(hr);
-
-            break;
-        case AttachCore:
-            break;
+                errorMessage += msgComFailed("TerminateProcesses", hr);
         }
-        m_d->setDebuggeeHandles(0, 0);
-        if (!errorMessage.isEmpty())
-            qWarning("exitDebugger: %s\n", qPrintable(errorMessage));
+        QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+        break;
+    }
+    setDebuggeeHandles(0, 0);
+    m_engine->killWatchTimer();
+    if (!errorMessage.isEmpty()) {
+        errorMessage = QString::fromLatin1("There were errors trying to end debugging: %1").arg(errorMessage);
+        m_debuggerManagerAccess->showDebuggerOutput(QLatin1String("error"), errorMessage);
+        qWarning("%s\n", qPrintable(errorMessage));
     }
-    killWatchTimer();
+}
+
+void CdbDebugEngine::exitDebugger()
+{
+    m_d->endDebugging();
+}
+
+void CdbDebugEngine::detachDebugger()
+{
+    m_d->endDebugging(CdbDebugEnginePrivate::EndDebuggingDetach);
 }
 
 CdbStackFrameContext *CdbDebugEnginePrivate::getStackFrameContext(int frameIndex, QString *errorMessage) const
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 3a993770c2..33640b9992 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -63,6 +63,7 @@ public:
     virtual void setToolTipExpression(const QPoint &pos, const QString &exp);
     virtual bool startDebugger();
     virtual void exitDebugger();
+    virtual void detachDebugger();
     virtual void updateWatchModel();
 
     virtual void stepExec();
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index 22ddf8ffc6..746d1993f6 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -132,6 +132,9 @@ struct CdbDebugEnginePrivate
     bool attemptBreakpointSynchronization(QString *errorMessage);
     void notifyCrashed();
 
+    enum EndDebuggingMode { EndDebuggingDetach, EndDebuggingTerminate, EndDebuggingAuto };
+    void endDebugging(EndDebuggingMode em = EndDebuggingAuto);
+
     static bool executeDebuggerCommand(CIDebugControl *ctrl, const QString &command, QString *errorMessage);
     static bool evaluateExpression(CIDebugControl *ctrl, const QString &expression, DEBUG_VALUE *v, QString *errorMessage);
 
-- 
GitLab