[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 04:49:38 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] [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;
More information about the lldb-commits
mailing list