aboutsummaryrefslogtreecommitdiff
path: root/gdbserver/win32-low.cc
diff options
context:
space:
mode:
authorPedro Alves <pedro@palves.net>2024-05-08 00:13:08 +0100
committerPedro Alves <pedro@palves.net>2024-05-17 20:14:23 +0100
commit650daf18185de6d2e51da2fe5cd0b94cc7fb9174 (patch)
tree32334c09a89bf0083e44ae965962f6d09694bb9a /gdbserver/win32-low.cc
parent6b25d11b012055936bb07179e246e04763cac27e (diff)
downloadbinutils-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.cc10
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 &current_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