forked from OSchip/llvm-project
Have a clean(er) shutdown when detaching from a process.
llvm-svn: 249206
This commit is contained in:
parent
a3df87b5a9
commit
6c3c0ed539
|
@ -304,20 +304,13 @@ DebuggerThread::DebugLoop()
|
||||||
{
|
{
|
||||||
case EXCEPTION_DEBUG_EVENT:
|
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);
|
ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
|
||||||
|
|
||||||
if (status == ExceptionResult::MaskException)
|
if (status == ExceptionResult::MaskException)
|
||||||
continue_status = DBG_CONTINUE;
|
continue_status = DBG_CONTINUE;
|
||||||
else if (status == ExceptionResult::SendToApplication)
|
else if (status == ExceptionResult::SendToApplication)
|
||||||
continue_status = DBG_EXCEPTION_NOT_HANDLED;
|
continue_status = DBG_EXCEPTION_NOT_HANDLED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CREATE_THREAD_DEBUG_EVENT:
|
case CREATE_THREAD_DEBUG_EVENT:
|
||||||
|
@ -377,6 +370,24 @@ DebuggerThread::DebugLoop()
|
||||||
ExceptionResult
|
ExceptionResult
|
||||||
DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
|
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);
|
bool first_chance = (info.dwFirstChance != 0);
|
||||||
|
|
||||||
m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
|
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",
|
"HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
|
||||||
first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
|
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,
|
ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
|
||||||
*m_active_exception);
|
*m_active_exception);
|
||||||
m_exception_pred.SetValue(result, eBroadcastNever);
|
m_exception_pred.SetValue(result, eBroadcastNever);
|
||||||
|
|
Loading…
Reference in New Issue