diff --git a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp index 3eb5e0f4da4d..cc661be63590 100644 --- a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp @@ -304,20 +304,13 @@ DebuggerThread::DebugLoop() { case EXCEPTION_DEBUG_EVENT: { - if (m_is_shutting_down) - { - // Don't perform any blocking operations while we're shutting down. That will - // cause TerminateProcess -> WaitForSingleObject to time out. - continue_status = DBG_EXCEPTION_NOT_HANDLED; - break; - } - ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId); if (status == ExceptionResult::MaskException) continue_status = DBG_CONTINUE; else if (status == ExceptionResult::SendToApplication) continue_status = DBG_EXCEPTION_NOT_HANDLED; + break; } case CREATE_THREAD_DEBUG_EVENT: @@ -377,6 +370,24 @@ DebuggerThread::DebugLoop() ExceptionResult DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id) { + if (m_is_shutting_down) + { + // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic exception that + // we use simply to wake up the DebuggerThread so that we can close out the debug loop. + if (m_pid_to_detach != 0 && info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) + { + WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS, + "Breakpoint exception is cue to detach from process 0x%x", + m_pid_to_detach); + ::DebugActiveProcessStop(m_pid_to_detach); + m_detached = true; + } + + // Don't perform any blocking operations while we're shutting down. That will + // cause TerminateProcess -> WaitForSingleObject to time out. + return ExceptionResult::SendToApplication; + } + bool first_chance = (info.dwFirstChance != 0); m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id)); @@ -384,18 +395,6 @@ DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thr "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x", first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id); - if (m_pid_to_detach != 0 && m_active_exception->GetExceptionCode() == EXCEPTION_BREAKPOINT) { - WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS, - "Breakpoint exception is cue to detach from process 0x%x", - m_pid_to_detach); - if (::DebugActiveProcessStop(m_pid_to_detach)) { - m_detached = true; - return ExceptionResult::MaskException; - } else { - WINLOG_IFANY(WINDOWS_LOG_PROCESS, "Failed to detach, treating as a regular breakpoint"); - } - } - ExceptionResult result = m_debug_delegate->OnDebugException(first_chance, *m_active_exception); m_exception_pred.SetValue(result, eBroadcastNever);