@@ -239,12 +239,13 @@ void DebuggerThread::DebugLoop() {
239239 BOOL wait_result = WaitForDebugEvent (&dbe, INFINITE);
240240 if (wait_result) {
241241 DWORD continue_status = DBG_CONTINUE;
242+ bool shutting_down = m_is_shutting_down;
242243 switch (dbe.dwDebugEventCode ) {
243244 default :
244245 llvm_unreachable (" Unhandle debug event code!" );
245246 case EXCEPTION_DEBUG_EVENT: {
246- ExceptionResult status =
247- HandleExceptionEvent ( dbe.u .Exception , dbe.dwThreadId );
247+ ExceptionResult status = HandleExceptionEvent (
248+ dbe.u .Exception , dbe.dwThreadId , shutting_down );
248249
249250 if (status == ExceptionResult::MaskException)
250251 continue_status = DBG_CONTINUE;
@@ -292,6 +293,45 @@ void DebuggerThread::DebugLoop() {
292293
293294 ::ContinueDebugEvent (dbe.dwProcessId, dbe.dwThreadId, continue_status);
294295
296+ // We have to DebugActiveProcessStop after ContinueDebugEvent, otherwise
297+ // the target process will crash
298+ if (shutting_down) {
299+ // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a
300+ // magic exception that we use simply to wake up the DebuggerThread so
301+ // that we can close out the debug loop.
302+ if (m_pid_to_detach != 0 &&
303+ (dbe.u .Exception .ExceptionRecord .ExceptionCode ==
304+ EXCEPTION_BREAKPOINT ||
305+ dbe.u .Exception .ExceptionRecord .ExceptionCode ==
306+ STATUS_WX86_BREAKPOINT)) {
307+ LLDB_LOG (log,
308+ " Breakpoint exception is cue to detach from process {0:x}" ,
309+ m_pid_to_detach.load ());
310+
311+ // detaching with leaving breakpoint exception event on the queue may
312+ // cause target process to crash so process events as possible since
313+ // target threads are running at this time, there is possibility to
314+ // have some breakpoint exception between last WaitForDebugEvent and
315+ // DebugActiveProcessStop but ignore for now.
316+ while (WaitForDebugEvent (&dbe, 0 )) {
317+ continue_status = DBG_CONTINUE;
318+ if (dbe.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
319+ !(dbe.u .Exception .ExceptionRecord .ExceptionCode ==
320+ EXCEPTION_BREAKPOINT ||
321+ dbe.u .Exception .ExceptionRecord .ExceptionCode ==
322+ STATUS_WX86_BREAKPOINT ||
323+ dbe.u .Exception .ExceptionRecord .ExceptionCode ==
324+ EXCEPTION_SINGLE_STEP))
325+ continue_status = DBG_EXCEPTION_NOT_HANDLED;
326+ ::ContinueDebugEvent (dbe.dwProcessId, dbe.dwThreadId,
327+ continue_status);
328+ }
329+
330+ ::DebugActiveProcessStop (m_pid_to_detach);
331+ m_detached = true ;
332+ }
333+ }
334+
295335 if (m_detached) {
296336 should_debug = false ;
297337 }
@@ -310,25 +350,18 @@ void DebuggerThread::DebugLoop() {
310350
311351ExceptionResult
312352DebuggerThread::HandleExceptionEvent (const EXCEPTION_DEBUG_INFO &info,
313- DWORD thread_id) {
353+ DWORD thread_id, bool shutting_down ) {
314354 Log *log = GetLog (WindowsLog::Event | WindowsLog::Exception);
315- if (m_is_shutting_down) {
316- // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
317- // exception that
318- // we use simply to wake up the DebuggerThread so that we can close out the
319- // debug loop.
320- if (m_pid_to_detach != 0 &&
355+ if (shutting_down) {
356+ bool is_breakpoint =
321357 (info.ExceptionRecord .ExceptionCode == EXCEPTION_BREAKPOINT ||
322- info.ExceptionRecord .ExceptionCode == STATUS_WX86_BREAKPOINT)) {
323- LLDB_LOG (log, " Breakpoint exception is cue to detach from process {0:x}" ,
324- m_pid_to_detach.load ());
325- ::DebugActiveProcessStop (m_pid_to_detach);
326- m_detached = true ;
327- }
358+ info.ExceptionRecord .ExceptionCode == STATUS_WX86_BREAKPOINT);
328359
329360 // Don't perform any blocking operations while we're shutting down. That
330361 // will cause TerminateProcess -> WaitForSingleObject to time out.
331- return ExceptionResult::SendToApplication;
362+ // We should not send breakpoint exceptions to the application.
363+ return is_breakpoint ? ExceptionResult::MaskException
364+ : ExceptionResult::SendToApplication;
332365 }
333366
334367 bool first_chance = (info.dwFirstChance != 0 );
0 commit comments