[Lldb-commits] [lldb] [lldb][Windows] Surface DebugBreakProcess Halt() as a SIGSTOP signal stop (PR #201885)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 8 09:39:35 PDT 2026


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/201885

>From c9b1d493fdbd6beb286d2d4f8effdb377e0b8509 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Thu, 4 Jun 2026 18:12:21 +0100
Subject: [PATCH 1/2] [lldb][Windows] Surface DebugBreakProcess Halt() as a
 SIGSTOP signal stop

---
 .../Windows/Common/NativeProcessWindows.cpp   | 36 +++++++++++++++++--
 .../Windows/Common/NativeProcessWindows.h     |  3 ++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index b235ab281bad6..7c4e6ebe25fee 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -173,8 +173,13 @@ NativeProcessWindows::GetThreadByID(lldb::tid_t thread_id) {
 Status NativeProcessWindows::Halt() {
   bool caused_stop = false;
   StateType state = GetState();
-  if (state != eStateStopped)
-    return HaltProcess(caused_stop);
+  if (state != eStateStopped) {
+    m_pending_halt = true;
+    Status err = HaltProcess(caused_stop);
+    if (err.Fail() || !caused_stop)
+      m_pending_halt = false;
+    return err;
+  }
   return Status();
 }
 
@@ -581,6 +586,33 @@ NativeProcessWindows::HandleBreakpointException(const ExceptionRecord &record) {
   // Any remaining STATUS_BREAKPOINT is a breakpoint instruction in the
   // program's own code (e.g. `__debugbreak()` or `__builtin_debugtrap()`).
   // Stop the debugger and let the user decide what to do.
+  if (m_pending_halt) {
+    LLDB_LOG(log,
+             "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
+             "{0:x}",
+             thread_id);
+    m_pending_halt = false;
+    ThreadStopInfo signal_info;
+    signal_info.reason = StopReason::eStopReasonSignal;
+    signal_info.signo = 19; // SIGSTOP on POSIX
+
+    // Halt all threads at the kernel level.
+    for (uint32_t i = 0; i < m_threads.size(); ++i) {
+      auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
+      if (t->DoStop().Fail())
+        exit(1);
+    }
+    if (!m_threads.empty()) {
+      auto first = static_cast<NativeThreadWindows *>(m_threads[0].get());
+      first->SetStopReason(signal_info, "interrupt");
+    }
+    SetCurrentThreadID(thread_id);
+    if (NativeThreadWindows *injected = GetThreadByID(thread_id))
+      injected->SetStopReason(signal_info, "interrupt");
+    SetState(eStateStopped, true);
+    return ExceptionResult::BreakInDebugger;
+  }
+
   std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
                              record.GetExceptionCode(), exception_addr)
                          .str();
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
index 95b85754ebdeb..02002d57eecaa 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.h
@@ -160,6 +160,9 @@ class NativeProcessWindows : public NativeProcessProtocol,
   /// launch / attach.
   bool m_initial_stop_seen = false;
 
+  /// Set when Halt() / Interrupt() schedules a DebugBreakProcess injection.
+  bool m_pending_halt = false;
+
   /// PseudoConsole for the lldb-server stdio-forwarding path.
   std::shared_ptr<PseudoConsole> m_pty;
 

>From 3fb25679c8fe500bc6c0a8f8bb4f116c6fe60577 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 8 Jun 2026 17:39:02 +0100
Subject: [PATCH 2/2] add log

---
 .../Plugins/Process/Windows/Common/NativeProcessWindows.cpp  | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 7c4e6ebe25fee..a0d4768767c71 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -599,8 +599,11 @@ NativeProcessWindows::HandleBreakpointException(const ExceptionRecord &record) {
     // Halt all threads at the kernel level.
     for (uint32_t i = 0; i < m_threads.size(); ++i) {
       auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
-      if (t->DoStop().Fail())
+      if (Status err = t->DoStop(); err.Fail()) {
+        LLDB_LOG(log, "Failed to stop thread {1}: {0}", t->GetID(),
+                 err.GetError());
         exit(1);
+      }
     }
     if (!m_threads.empty()) {
       auto first = static_cast<NativeThreadWindows *>(m_threads[0].get());



More information about the lldb-commits mailing list