[PATCH v2 27/47] Windows gdb+gdbserver: Make last_sig per-thread state

Pedro Alves
2025-05-19T13:33:15Z

With non-stop mode, each thread is controlled independently of the
others, and each thread has its own independent reason for its last
stop.

Thus, any thread-specific state that is currently per-process must be
converted to per-thread state.

This patch converts windows_process_info::last_sig to per-thread
state, moving it to windows_thread_info instead.

This adjusts both native gdb and gdbserver.

Change-Id: Ie8c673a819be445753d967afd3a6084565648448
---
gdb/nat/windows-nat.c | 8 +++++---
gdb/nat/windows-nat.h | 5 ++++-
gdb/windows-nat.c | 10 +++-------
gdbserver/win32-low.cc | 7 +++----
4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 53d891f65d0..864788ec125 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -359,8 +359,6 @@ windows_process_info::handle_exception (DEBUG_EVENT &current_event,

memcpy (&siginfo_er, rec, sizeof siginfo_er);

- last_sig = GDB_SIGNAL_0;
-
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION:
@@ -494,7 +492,11 @@ windows_process_info::handle_exception (DEBUG_EVENT &current_event,
}

if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
- last_sig = ourstatus->sig ();
+ {
+ ptid_t ptid (current_event.dwProcessId, current_event.dwThreadId, 0);
+ windows_thread_info *th = find_thread (ptid);
+ th->last_sig = ourstatus->sig ();
+ }

return result;

diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 0b89c751e89..71cb118f5d6 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -104,6 +104,10 @@ struct windows_thread_info
thread. */
DEBUG_EVENT last_event {};

+ /* The last signal reported for this thread, extracted out of
+ last_event. */
+ enum gdb_signal last_sig = GDB_SIGNAL_0;
+
/* The context of the thread, including any manipulations. */
union
{
@@ -147,7 +151,6 @@ struct windows_process_info
HANDLE handle = 0;
DWORD process_id = 0;
DWORD main_thread_id = 0;
- enum gdb_signal last_sig = GDB_SIGNAL_0;

/* Contents of $_siginfo */
EXCEPTION_RECORD siginfo_er {};
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 8ccb7048665..87cf5e1a4e8 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1258,6 +1258,7 @@ windows_per_inferior::continue_one_thread (windows_thread_info *th,
});

th->resume ();
+ th->last_sig = GDB_SIGNAL_0;
}

/* Resume thread specified by ID, or all artificially suspended
@@ -1358,7 +1359,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
DEBUG_EXCEPT ("Cannot continue with signal %d here. "
"Not stopped for EXCEPTION_DEBUG_EVENT", sig);
}
- else if (sig == windows_process.last_sig)
+ else if (sig == th->last_sig)
continue_status = DBG_EXCEPTION_NOT_HANDLED;
else
#if 0
@@ -1382,11 +1383,9 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
}
#endif
DEBUG_EXCEPT ("Can only continue with received signal %d.",
- windows_process.last_sig);
+ th->last_sig);
}

- windows_process.last_sig = GDB_SIGNAL_0;
-
windows_process.with_context (th, [&] (auto *context)
{
if (step)
@@ -1486,8 +1485,6 @@ windows_nat_target::get_windows_debug_event
}
}

- windows_process.last_sig = GDB_SIGNAL_0;
-
if ((options & TARGET_WNOHANG) != 0 && !m_debug_event_pending)
{
ourstatus->set_ignore ();
@@ -1806,7 +1803,6 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
{
struct inferior *inf;

- windows_process.last_sig = GDB_SIGNAL_0;
windows_process.open_process_used = 0;
#ifdef __CYGWIN__
windows_process.cygwin_load_start = 0;
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index a4000980f67..c3e35a6f602 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -289,7 +289,6 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
{
struct process_info *proc;

- windows_process.last_sig = GDB_SIGNAL_0;
windows_process.handle = proch;
windows_process.process_id = pid;
windows_process.main_thread_id = 0;
@@ -396,6 +395,7 @@ continue_one_thread (thread_info *thread, int thread_id)
}

th->resume ();
+ th->last_sig = GDB_SIGNAL_0;
}
}
}
@@ -758,11 +758,11 @@ resume_one_thread (thread_info *thread, bool step, gdb_signal sig,
"Not stopped for EXCEPTION_DEBUG_EVENT.\n",
gdb_signal_to_string (sig)));
}
- else if (sig == windows_process.last_sig)
+ else if (sig == th->last_sig)
*continue_status = DBG_EXCEPTION_NOT_HANDLED;
else
OUTMSG (("Can only continue with received signal %s.\n",
- gdb_signal_to_string (windows_process.last_sig)));
+ gdb_signal_to_string (th->last_sig)));
}

win32_prepare_to_resume (th);
@@ -957,7 +957,6 @@ get_child_debug_event (DWORD *continue_status,
{
ptid_t ptid;

- windows_process.last_sig = GDB_SIGNAL_0;
ourstatus->set_spurious ();
*continue_status = DBG_CONTINUE;

--
2.49.0