diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp index b235ab281bad6..aa0d08b90f862 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,32 @@ 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(m_threads[i].get()); + if (Status err = t->DoStop(); err.Fail()) { + LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(), + err.GetError()); + exit(1); + } + } + 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 m_pty;