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:
234943344f/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.

Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ifd6889a8afc041fad33cd1c4500e38941da6781b
commit-id:c4d2c92e
This commit is contained in:
Pedro Alves 2023-05-09 10:27:04 +01:00
parent db040a86c8
commit 555cee0edf
4 changed files with 10 additions and 8 deletions

View file

@ -185,7 +185,6 @@ aarch64_windows_nat_target::fill_thread_context (windows_thread_info *th)
if (context->ContextFlags == 0)
{
th->suspend ();
context->ContextFlags = WindowsContext<decltype(context)>::all;
CHECK (get_thread_context (th->h, context));
}

View file

@ -710,12 +710,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<unsigned> err;
do_synchronously ([&] ()
@ -1191,6 +1185,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;

View file

@ -111,7 +111,6 @@ x86_windows_nat_target::fill_thread_context (windows_thread_info *th)
{
if (context->ContextFlags == 0)
{
th->suspend ();
context->ContextFlags = WindowsContext<decltype(context)>::all;
CHECK (get_thread_context (th->h, context));
}

View file

@ -1188,6 +1188,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: