diff options
author | Pedro Alves <pedro@palves.net> | 2024-05-08 00:13:08 +0100 |
---|---|---|
committer | Pedro Alves <pedro@palves.net> | 2024-05-17 20:14:23 +0100 |
commit | 650daf18185de6d2e51da2fe5cd0b94cc7fb9174 (patch) | |
tree | 32334c09a89bf0083e44ae965962f6d09694bb9a /gdbserver/win32-low.cc | |
parent | 6b25d11b012055936bb07179e246e04763cac27e (diff) | |
download | binutils-650daf18185de6d2e51da2fe5cd0b94cc7fb9174.zip binutils-650daf18185de6d2e51da2fe5cd0b94cc7fb9174.tar.gz binutils-650daf18185de6d2e51da2fe5cd0b94cc7fb9174.tar.bz2 |
Windows gdb: Add non-stop support
This patch adds non-stop support to the native Windows target.
This is made possible by the ContinueDebugEvent DBG_REPLY_LATER flag:
https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-continuedebugevent
Supported in Windows 10, version 1507 or above, this flag causes
dwThreadId to replay the existing breaking event after the target
continues. By calling the SuspendThread API against dwThreadId, a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
debugger can resume other threads in the process and later return to
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the breaking.
^^^^^^^^^^^^
The patch adds a new comment section in gdb/windows-nat.c providing an
overall picture of how all-stop / non-stop work.
Without DBG_REPLY_LATER, if we SuspendThread the thread, and then
immediately ContinueDebugThread(DBG_CONTINUE) before getting back to
the prompt, we could still have non-stop mode working, however, then
users wouldn't have a chance to decide whether to pass the signal to
the inferior the next time they resume the program, as that is done by
passing DBG_EXCEPTION_NOT_HANDLED to ContinueDebugEvent, and that has
already been called.
The patch adds that DBG_REPLY_LATER handling, and also adds support
for target_stop, so the core can pause threads at its discretion.
This pausing does not use the same mechanisms used in
windows_nat_target::interrupt, as those inject a new thread in the
inferior. Instead, for each thread the core wants paused, it uses
SuspendThread, and enqueues a pending GDB_SIGNAL_0 stop on the thread.
Since DBG_REPLY_LATER only exists on Windows 10 and later, we only
enable non-stop mode on Windows 10 and later.
Since having the target backend work in non-stop mode adds features
compared to old all-stop mode (signal/exception passing/suppression is
truly per-thread), this patch also switches the backend to do
all-stop-on-top-of-non-stop, by having
windows_nat_target::always_non_stop_p return true if non-stop mode is
possible. To be clear, this just changes how the backend works in
coordination with infrun. The user-visible mode default mode is still
all-stop. The difference is that infrun is responsible for stopping
all threads when needed, instead of the backend (actually the kernel)
always doing that before reporting an event to infrun.
There is no displaced stepping support, but that's "just" a missed
optimization to be done later.
Cygwin signals handling was a major headache, but I managed to get it
working. See the "Cygwin signals" description section I added at the
top of windows-nat.c.
Change-Id: Id71aef461c43c244120635b5bedc638fe77c31fb
Diffstat (limited to 'gdbserver/win32-low.cc')
-rw-r--r-- | gdbserver/win32-low.cc | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 65b01dc..b15d8d0 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -625,7 +625,7 @@ win32_process_target::attach (unsigned long pid) /* See nat/windows-nat.h. */ -DWORD +bool gdbserver_windows_process::handle_output_debug_string (const DEBUG_EVENT ¤t_event, struct target_waitstatus *ourstatus) @@ -636,7 +636,7 @@ gdbserver_windows_process::handle_output_debug_string DWORD nbytes = current_event.u.DebugString.nDebugStringLength; if (nbytes == 0) - return 0; + return false; if (nbytes > READ_BUFFER_LEN) nbytes = READ_BUFFER_LEN; @@ -655,7 +655,7 @@ gdbserver_windows_process::handle_output_debug_string else { if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) - return 0; + return false; } if (!startswith (s, "cYg")) @@ -663,14 +663,14 @@ gdbserver_windows_process::handle_output_debug_string if (!server_waiting) { OUTMSG2(("%s", s)); - return 0; + return false; } monitor_output (s); } #undef READ_BUFFER_LEN - return 0; + return false; } static void |