[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