Author: Charles Zablit
Date: 2026-06-29T20:52:29+01:00
New Revision: 1915dfacc28cec48e433cdab5352dfeaba00d2ed

URL: 
https://github.com/llvm/llvm-project/commit/1915dfacc28cec48e433cdab5352dfeaba00d2ed
DIFF: 
https://github.com/llvm/llvm-project/commit/1915dfacc28cec48e433cdab5352dfeaba00d2ed.diff

LOG: [lldb][Windows] handle exception first to keep track of the stop reason 
(#206469)

`NativeProcessWindows::OnDebugException` called
`ProcessDebugger::OnDebugException` before handling the exception. That
ordering races on the first breakpoint:

1. The launch thread blocks in
`ProcessDebugger::WaitForDebuggerConnection`, waiting on
`m_initial_stop_event`.
2. A debug exception arrives and
`NativeProcessWindows::OnDebugException` is called.
3. It calls `ProcessDebugger::OnDebugException` first, which signals
`m_initial_stop_event` and wakes the launch thread.
4. Only then does `NativeProcessWindows::Handle...Exception` set the
process state and stop reason.

When the bug occurs, the launch thread wakes up (3) before the stop
reason is set (4), and the first stop can be reported with a missing or
wrong reason.

This patch handles the exception first, then calls
`ProcessDebugger::OnDebugException`.

It fixes the following flaky tests:

```
lldb-api :: commands/process/reverse-continue/TestReverseContinue.py
lldb-api :: functionalities/reverse-execution/TestReverseContinueBreakpoints.py
lldb-api :: functionalities/reverse-execution/TestReverseContinueWatchpoints.py
lldb-api :: tools/lldb-server/TestGdbRemoteAttach.py
lldb-api :: tools/lldb-server/TestGdbRemoteExitCode.py
lldb-api :: tools/lldb-server/TestGdbRemoteExpeditedRegisters.py
lldb-api :: tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
lldb-api :: tools/lldb-server/TestGdbRemote_qThreadStopInfo.py
lldb-api :: tools/lldb-server/TestLldbGdbServer.py
lldb-api :: tools/lldb-server/TestNonStop.py
lldb-api :: tools/lldb-server/register-reading/TestGdbRemoteGPacket.py
```

Added: 
    

Modified: 
    lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp

Removed: 
    


################################################################################
diff  --git 
a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp 
b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 889a2e743c07f..ce4fa3d1f0152 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -653,19 +653,26 @@ NativeProcessWindows::OnDebugException(bool first_chance,
                                        const ExceptionRecord &record) {
   llvm::sys::ScopedLock lock(m_mutex);
 
-  // Let the debugger establish the internal status.
-  ProcessDebugger::OnDebugException(first_chance, record);
-
+  // Handle the exception first to keep track of the stop reason.
+  ExceptionResult result;
   switch (record.GetExceptionValue()) {
   case DWORD(STATUS_SINGLE_STEP):
   case STATUS_WX86_SINGLE_STEP:
-    return HandleSingleStepException(record);
+    result = HandleSingleStepException(record);
+    break;
   case DWORD(STATUS_BREAKPOINT):
   case STATUS_WX86_BREAKPOINT:
-    return HandleBreakpointException(record);
+    result = HandleBreakpointException(record);
+    break;
   default:
-    return HandleGenericException(first_chance, record);
+    result = HandleGenericException(first_chance, record);
+    break;
   }
+
+  // Let the debugger establish the internal status.
+  ProcessDebugger::OnDebugException(first_chance, record);
+
+  return result;
 }
 
 void NativeProcessWindows::OnCreateThread(const HostThread &new_thread) {


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to