diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index a027ae3c3c7826afd0b3ea721302e83044e2900a..789936f3ea697b950289721ff3ebe8afb8645d02 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 3a993770c2df6d04183141a5e619f40bc63742fe..33640b99926d560b27a2d424c37539ac396011e1 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 22ddf8ffc611a73a0a05b1117c098b896a856274..746d1993f6b14d12f8558675bb7fe6cc824e9eca 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);