From b1497491008b9351fa95c5f08fbe361a014dabba Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Tue, 9 May 2023 10:27:04 +0100 Subject: [PATCH] Windows gdb+gdbserver: Move suspending thread to when returning event The current code suspends a thread just before calling GetThreadContext. You can only call GetThreadContext if the thread is suspended. But, after WaitForDebugEvent, all threads are implicitly suspended. So I don't think we even needed to call SuspendThread explictly at all before our GetThreadContext calls. However, suspending threads when we're about to present a stop to gdb simplifies adding non-stop support later. This way, the windows SuspendThread state corresponds to whether a thread is suspended or resumed from the core's perspective. Curiously, I noticed that Wine's winedbg does something similar: https://github.com/wine-mirror/wine/blob/234943344f7495d1e072338f0e06fa2d5cbf0aa1/programs/winedbg/gdbproxy.c#L651 This makes it much easier to reason about a thread's suspend state, and simplifies adding non-stop mode later on. Change-Id: Ifd6889a8afc041fad33cd1c4500e38941da6781b --- gdb/windows-nat.c | 12 +++++------- gdbserver/win32-low.cc | 5 +++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index f1ec8837e82..a81a7eebfe9 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -706,7 +706,6 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r) { if (context->ContextFlags == 0) { - th->suspend (); context->ContextFlags = WindowsContext::all; CHECK (get_thread_context (th->h, context)); } @@ -1233,12 +1232,6 @@ windows_nat_target::windows_continue (DWORD continue_status, int id, th->resume (); } - else - { - /* When single-stepping a specific thread, other threads must - be suspended. */ - th->suspend (); - } std::optional err; do_synchronously ([&] () @@ -1717,6 +1710,11 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, th->stopped_at_software_breakpoint = true; th->pc_adjusted = false; } + + /* All-stop, suspend all threads until they are + explicitly resumed. */ + for (auto &thr : windows_process.thread_list) + thr->suspend (); } return result; diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index c99248d37cb..a23a41b9c02 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -1194,6 +1194,11 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus, OUTMSG2 (("Child Stopped with signal = %d \n", ourstatus->sig ())); maybe_adjust_pc (); + + /* All-stop, suspend all threads until they are explicitly + resumed. */ + for_each_thread (suspend_one_thread); + return debug_event_ptid (&windows_process.current_event); } default: -- 2.47.2