From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [pushed 19/28] Windows gdb+gdbserver: Make current_event per-thread state
Date: Fri, 24 Apr 2026 21:44:59 +0100 [thread overview]
Message-ID: <20260424204508.1343973-20-pedro@palves.net> (raw)
In-Reply-To: <20260424204508.1343973-1-pedro@palves.net>
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::current_event, moving it to
windows_thread_info instead, renamed to last_event.
Since each thread will have its own copy of its last Windows debug
event, we no longer need the same information stored in struct
pending_stop.
Since windows_process.current_event no longer exists, we need to pass
the current event as parameter to a number of methods.
This adjusts both native gdb and gdbserver.
Approved-By: Tom Tromey <tom@tromey.com>
Change-Id: Ice09a5d932c912210608d5af25e1898f823e3c99
commit-id:ca7e9182
---
gdb/nat/windows-nat.c | 13 +++---
gdb/nat/windows-nat.h | 24 ++++++-----
gdb/windows-nat.c | 90 +++++++++++++++++++++++-------------------
gdb/windows-nat.h | 10 +++--
gdbserver/win32-low.cc | 68 +++++++++++++++----------------
gdbserver/win32-low.h | 5 ++-
6 files changed, 112 insertions(+), 98 deletions(-)
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 11151fdc28a..4adca4afa64 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -300,8 +300,10 @@ get_image_name (HANDLE h, void *address, int unicode)
/* See nat/windows-nat.h. */
bool
-windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+windows_process_info::handle_ms_vc_exception (const DEBUG_EVENT ¤t_event)
{
+ const EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
+
if (rec->NumberParameters >= 3
&& (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
{
@@ -342,7 +344,8 @@ windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
#define MS_VC_EXCEPTION 0x406d1388
handle_exception_result
-windows_process_info::handle_exception (struct target_waitstatus *ourstatus,
+windows_process_info::handle_exception (DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus,
bool debug_exceptions)
{
#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
@@ -470,7 +473,7 @@ windows_process_info::handle_exception (struct target_waitstatus *ourstatus,
break;
case MS_VC_EXCEPTION:
DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
- if (handle_ms_vc_exception (rec))
+ if (handle_ms_vc_exception (current_event))
{
ourstatus->set_stopped (GDB_SIGNAL_TRAP);
result = HANDLE_EXCEPTION_IGNORED;
@@ -610,11 +613,11 @@ windows_process_info::add_dll (LPVOID load_addr)
/* See nat/windows-nat.h. */
void
-windows_process_info::dll_loaded_event ()
+windows_process_info::dll_loaded_event (const DEBUG_EVENT ¤t_event)
{
gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);
- LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
+ const LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
const char *dll_name;
/* Try getting the DLL name via the lpImageName field of the event.
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h
index 8d97ecc4cb6..4710ec39130 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -46,10 +46,6 @@ struct pending_stop
/* The target waitstatus we computed. TARGET_WAITKIND_IGNORE if the
thread does not have a pending stop. */
target_waitstatus status;
-
- /* The event. A few fields of this can be referenced after a stop,
- and it seemed simplest to store the entire event. */
- DEBUG_EVENT event;
};
@@ -104,6 +100,10 @@ struct windows_thread_info
process them once the step has completed. See PR gdb/22992. */
struct pending_stop pending_stop {};
+ /* The last Windows event returned by WaitForDebugEvent for this
+ thread. */
+ DEBUG_EVENT last_event {};
+
/* The context of the thread, including any manipulations. */
union
{
@@ -149,10 +149,6 @@ struct windows_process_info
DWORD main_thread_id = 0;
enum gdb_signal last_sig = GDB_SIGNAL_0;
- /* The current debug event from WaitForDebugEvent or from a pending
- stop. */
- DEBUG_EVENT current_event {};
-
/* Contents of $_siginfo */
EXCEPTION_RECORD siginfo_er {};
@@ -176,7 +172,8 @@ struct windows_process_info
a Cygwin signal. Otherwise just print the string as a warning.
This function must be supplied by the embedding application. */
- virtual DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) = 0;
+ virtual DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus) = 0;
/* Handle a DLL load event.
@@ -197,7 +194,7 @@ struct windows_process_info
This function must be supplied by the embedding application. */
- virtual void handle_unload_dll () = 0;
+ virtual void handle_unload_dll (const DEBUG_EVENT ¤t_event) = 0;
/* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
application a chance to change it to be considered "unhandled".
@@ -207,11 +204,12 @@ struct windows_process_info
virtual bool handle_access_violation (const EXCEPTION_RECORD *rec) = 0;
handle_exception_result handle_exception
- (struct target_waitstatus *ourstatus, bool debug_exceptions);
+ (DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus, bool debug_exceptions);
/* Call to indicate that a DLL was loaded. */
- void dll_loaded_event ();
+ void dll_loaded_event (const DEBUG_EVENT ¤t_event);
/* Iterate over all DLLs currently mapped by our inferior, and
add them to our list of solibs. */
@@ -247,7 +245,7 @@ struct windows_process_info
Return true if the exception was handled; return false otherwise. */
- bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
+ bool handle_ms_vc_exception (const DEBUG_EVENT ¤t_event);
/* Iterate over all DLLs currently mapped by our inferior, looking for
a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 614d85ac8f7..64c53b53934 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -557,7 +557,7 @@ windows_per_inferior::handle_load_dll (const char *dll_name, LPVOID base)
/* See nat/windows-nat.h. */
void
-windows_per_inferior::handle_unload_dll ()
+windows_per_inferior::handle_unload_dll (const DEBUG_EVENT ¤t_event)
{
LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
@@ -620,7 +620,8 @@ signal_event_command (const char *args, int from_tty)
DWORD
windows_per_inferior::handle_output_debug_string
- (struct target_waitstatus *ourstatus)
+ (const DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus)
{
DWORD thread_id = 0;
@@ -753,11 +754,11 @@ windows_nat_target::windows_continue (DWORD continue_status, int id,
/* Called in pathological case where Windows fails to send a
CREATE_PROCESS_DEBUG_EVENT after an attach. */
DWORD
-windows_nat_target::fake_create_process ()
+windows_nat_target::fake_create_process (const DEBUG_EVENT ¤t_event)
{
windows_process->handle
= OpenProcess (PROCESS_ALL_ACCESS, FALSE,
- windows_process->current_event.dwProcessId);
+ current_event.dwProcessId);
if (windows_process->handle != NULL)
windows_process->open_process_used = 1;
else
@@ -766,12 +767,11 @@ windows_nat_target::fake_create_process ()
throw_winerror_with_name (_("OpenProcess call failed"), err);
/* We can not debug anything in that case. */
}
- add_thread (ptid_t (windows_process->current_event.dwProcessId,
- windows_process->current_event.dwThreadId, 0),
- windows_process->current_event.u.CreateThread.hThread,
- windows_process->current_event.u.CreateThread.lpThreadLocalBase,
+ add_thread (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
+ current_event.u.CreateThread.hThread,
+ current_event.u.CreateThread.lpThreadLocalBase,
true /* main_thread_p */);
- return windows_process->current_event.dwThreadId;
+ return current_event.dwThreadId;
}
void
@@ -788,6 +788,13 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
if (resume_all)
ptid = inferior_ptid;
+ DEBUG_EXEC ("pid=%d, tid=0x%x, step=%d, sig=%d",
+ ptid.pid (), (unsigned) ptid.lwp (), step, sig);
+
+ /* Get currently selected thread. */
+ th = windows_process->find_thread (inferior_ptid);
+ gdb_assert (th != nullptr);
+
if (sig != GDB_SIGNAL_0)
{
/* Note it is OK to call get_last_debug_event_ptid() from the
@@ -800,8 +807,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
DEBUG_EXCEPT ("Cannot continue with signal %d here. "
"Not last-event thread", sig);
}
- else if (windows_process->current_event.dwDebugEventCode
- != EXCEPTION_DEBUG_EVENT)
+ else if (th->last_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
{
DEBUG_EXCEPT ("Cannot continue with signal %d here. "
"Not stopped for EXCEPTION_DEBUG_EVENT", sig);
@@ -818,7 +824,7 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
for (const xlate_exception &x : xlate)
if (x.us == sig)
{
- current_event.u.Exception.ExceptionRecord.ExceptionCode
+ th->last_event.u.Exception.ExceptionRecord.ExceptionCode
= x.them;
continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
@@ -835,12 +841,8 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
windows_process->last_sig = GDB_SIGNAL_0;
- DEBUG_EXEC ("pid=%d, tid=0x%x, step=%d, sig=%d",
- ptid.pid (), (unsigned) ptid.lwp (), step, sig);
-
/* Get context for currently selected thread. */
- th = windows_process->find_thread (inferior_ptid);
- if (th != nullptr && step)
+ if (step)
{
/* Single step by setting t bit. */
regcache *regcache = get_thread_regcache (inferior_thread ());
@@ -915,7 +917,8 @@ windows_nat_target::stop (ptid_t ptid)
ptid_t
windows_nat_target::get_windows_debug_event
- (int pid, struct target_waitstatus *ourstatus, target_wait_flags options)
+ (int pid, struct target_waitstatus *ourstatus, target_wait_flags options,
+ DEBUG_EVENT *current_event)
{
DWORD continue_status, event_code;
DWORD thread_id = 0;
@@ -933,7 +936,7 @@ windows_nat_target::get_windows_debug_event
thread_id = th->tid;
*ourstatus = th->pending_stop.status;
th->pending_stop.status.set_ignore ();
- windows_process->current_event = th->pending_stop.event;
+ *current_event = th->last_event;
ptid_t ptid (windows_process->process_id, thread_id);
windows_process->invalidate_thread_context (th.get ());
@@ -942,7 +945,6 @@ windows_nat_target::get_windows_debug_event
}
windows_process->last_sig = GDB_SIGNAL_0;
- DEBUG_EVENT *current_event = &windows_process->current_event;
if ((options & TARGET_WNOHANG) != 0 && !m_debug_event_pending)
{
@@ -950,11 +952,11 @@ windows_nat_target::get_windows_debug_event
return minus_one_ptid;
}
- wait_for_debug_event_main_thread (&windows_process->current_event);
+ wait_for_debug_event_main_thread (current_event);
continue_status = DBG_CONTINUE;
- event_code = windows_process->current_event.dwDebugEventCode;
+ event_code = current_event->dwDebugEventCode;
ourstatus->set_spurious ();
switch (event_code)
@@ -972,7 +974,7 @@ windows_nat_target::get_windows_debug_event
/* Kludge around a Windows bug where first event is a create
thread event. Caused when attached process does not have
a main thread. */
- thread_id = fake_create_process ();
+ thread_id = fake_create_process (*current_event);
if (thread_id)
windows_process->saw_create++;
}
@@ -1069,7 +1071,7 @@ windows_nat_target::get_windows_debug_event
break;
try
{
- windows_process->dll_loaded_event ();
+ windows_process->dll_loaded_event (*current_event);
}
catch (const gdb_exception &ex)
{
@@ -1089,7 +1091,7 @@ windows_nat_target::get_windows_debug_event
break;
try
{
- windows_process->handle_unload_dll ();
+ windows_process->handle_unload_dll (*current_event);
}
catch (const gdb_exception &ex)
{
@@ -1106,7 +1108,8 @@ windows_nat_target::get_windows_debug_event
"EXCEPTION_DEBUG_EVENT");
if (windows_process->saw_create != 1)
break;
- switch (windows_process->handle_exception (ourstatus, debug_exceptions))
+ switch (windows_process->handle_exception (*current_event,
+ ourstatus, debug_exceptions))
{
case HANDLE_EXCEPTION_UNHANDLED:
default:
@@ -1128,7 +1131,8 @@ windows_nat_target::get_windows_debug_event
"OUTPUT_DEBUG_STRING_EVENT");
if (windows_process->saw_create != 1)
break;
- thread_id = windows_process->handle_output_debug_string (ourstatus);
+ thread_id = windows_process->handle_output_debug_string (*current_event,
+ ourstatus);
break;
default:
@@ -1153,6 +1157,8 @@ windows_nat_target::get_windows_debug_event
const ptid_t ptid = ptid_t (current_event->dwProcessId, thread_id, 0);
windows_thread_info *th = windows_process->find_thread (ptid);
+ th->last_event = *current_event;
+
if (th->suspended)
{
/* Pending stop. See the comment by the definition of
@@ -1168,8 +1174,8 @@ windows_nat_target::get_windows_debug_event
th->stopped_at_software_breakpoint = true;
th->pc_adjusted = false;
}
+
th->pending_stop.status = *ourstatus;
- th->pending_stop.event = *current_event;
ourstatus->set_ignore ();
continue_last_debug_event_main_thread
@@ -1195,7 +1201,10 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
while (1)
{
- ptid_t result = get_windows_debug_event (pid, ourstatus, options);
+ DEBUG_EVENT current_event;
+
+ ptid_t result = get_windows_debug_event (pid, ourstatus, options,
+ ¤t_event);
if ((options & TARGET_WNOHANG) != 0
&& ourstatus->kind () == TARGET_WAITKIND_IGNORE)
@@ -1214,11 +1223,11 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
windows_thread_info *th = windows_process->find_thread (result);
th->stopped_at_software_breakpoint = false;
- if (windows_process->current_event.dwDebugEventCode
+ if (current_event.dwDebugEventCode
== EXCEPTION_DEBUG_EVENT
- && ((windows_process->current_event.u.Exception.ExceptionRecord.ExceptionCode
+ && ((current_event.u.Exception.ExceptionRecord.ExceptionCode
== EXCEPTION_BREAKPOINT)
- || (windows_process->current_event.u.Exception.ExceptionRecord.ExceptionCode
+ || (current_event.u.Exception.ExceptionRecord.ExceptionCode
== STATUS_WX86_BREAKPOINT))
&& windows_process->windows_initialization_done)
{
@@ -1261,8 +1270,6 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
windows_process->cygwin_load_end = 0;
#endif
windows_process->process_id = pid;
- memset (&windows_process->current_event, 0,
- sizeof (windows_process->current_event));
inf = current_inferior ();
if (!inf->target_is_pushed (this))
inf->push_target (this);
@@ -1292,7 +1299,10 @@ windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
&& status.kind () != TARGET_WAITKIND_SPURIOUS)
break;
- this->resume (minus_one_ptid, 0, GDB_SIGNAL_0);
+ /* Don't use windows_nat_target::resume here because that
+ assumes that inferior_ptid points at a valid thread, and we
+ haven't switched to any thread yet. */
+ windows_continue (DBG_CONTINUE, -1);
}
switch_to_thread (this->find_thread (last_ptid));
@@ -1575,7 +1585,7 @@ windows_nat_target::detach (inferior *inf, int from_tty)
if (process_alive)
do_synchronously ([&] ()
{
- if (!DebugActiveProcessStop (windows_process->current_event.dwProcessId))
+ if (!DebugActiveProcessStop (windows_process->process_id))
err = (unsigned) GetLastError ();
else
DebugSetProcessKillOnExit (FALSE);
@@ -1586,7 +1596,7 @@ windows_nat_target::detach (inferior *inf, int from_tty)
{
std::string msg
= string_printf (_("Can't detach process %u"),
- (unsigned) windows_process->current_event.dwProcessId);
+ windows_process->process_id);
throw_winerror_with_name (msg.c_str (), *err);
}
@@ -2383,9 +2393,9 @@ windows_nat_target::kill ()
{
if (!windows_continue (DBG_CONTINUE, -1, WCONT_KILLED))
break;
- wait_for_debug_event_main_thread (&windows_process->current_event);
- if (windows_process->current_event.dwDebugEventCode
- == EXIT_PROCESS_DEBUG_EVENT)
+ DEBUG_EVENT current_event;
+ wait_for_debug_event_main_thread (¤t_event);
+ if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
break;
}
diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h
index 0f586cd195e..15a177214f2 100644
--- a/gdb/windows-nat.h
+++ b/gdb/windows-nat.h
@@ -63,9 +63,10 @@ DEF_ENUM_FLAGS_TYPE (windows_continue_flag, windows_continue_flags);
struct windows_per_inferior : public windows_nat::windows_process_info
{
windows_thread_info *find_thread (ptid_t ptid) override;
- DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) override;
+ DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus) override;
void handle_load_dll (const char *dll_name, LPVOID base) override;
- void handle_unload_dll () override;
+ void handle_unload_dll (const DEBUG_EVENT ¤t_event) override;
bool handle_access_violation (const EXCEPTION_RECORD *rec) override;
/* Invalidate the thread context. */
@@ -172,7 +173,8 @@ struct windows_nat_target : public inf_child_target
const char *thread_name (struct thread_info *) override;
ptid_t get_windows_debug_event (int pid, struct target_waitstatus *ourstatus,
- target_wait_flags options);
+ target_wait_flags options,
+ DEBUG_EVENT *current_event);
void do_initial_windows_stuff (DWORD pid, bool attaching);
@@ -244,7 +246,7 @@ struct windows_nat_target : public inf_child_target
windows_thread_info *add_thread (ptid_t ptid, HANDLE h, void *tlb,
bool main_thread_p);
void delete_thread (ptid_t ptid, DWORD exit_code, bool main_thread_p);
- DWORD fake_create_process ();
+ DWORD fake_create_process (const DEBUG_EVENT ¤t_event);
void continue_one_thread (windows_thread_info *th,
windows_continue_flags cont_flags);
diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 5caec960082..aa484fcda4a 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -291,9 +291,6 @@ do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
windows_process.open_process_used = true;
- memset (&windows_process.current_event, 0,
- sizeof (windows_process.current_event));
-
#ifdef __x86_64__
BOOL wow64;
if (!IsWow64Process (proch, &wow64))
@@ -590,7 +587,8 @@ win32_process_target::attach (unsigned long pid)
DWORD
gdbserver_windows_process::handle_output_debug_string
- (struct target_waitstatus *ourstatus)
+ (const DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus)
{
#define READ_BUFFER_LEN 1024
CORE_ADDR addr;
@@ -658,14 +656,13 @@ win32_process_target::kill (process_info *process)
{
if (!child_continue_for_kill (DBG_CONTINUE, -1))
break;
- if (!wait_for_debug_event (&windows_process.current_event, INFINITE))
+ DEBUG_EVENT current_event;
+ if (!wait_for_debug_event (¤t_event, INFINITE))
break;
- if (windows_process.current_event.dwDebugEventCode
- == EXIT_PROCESS_DEBUG_EVENT)
+ if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
break;
- else if (windows_process.current_event.dwDebugEventCode
- == OUTPUT_DEBUG_STRING_EVENT)
- windows_process.handle_output_debug_string (nullptr);
+ else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
+ windows_process.handle_output_debug_string (current_event, nullptr);
}
win32_clear_process ();
@@ -744,8 +741,7 @@ resume_one_thread (thread_info *thread, bool step, gdb_signal sig,
OUTMSG (("Cannot continue with signal %d here. "
"Not last-event thread", sig));
}
- else if (windows_process.current_event.dwDebugEventCode
- != EXCEPTION_DEBUG_EVENT)
+ else if (th->last_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
{
OUTMSG (("Cannot continue with signal %s here. "
"Not stopped for EXCEPTION_DEBUG_EVENT.\n",
@@ -884,7 +880,7 @@ gdbserver_windows_process::handle_load_dll (const char *name, LPVOID base)
/* See nat/windows-nat.h. */
void
-gdbserver_windows_process::handle_unload_dll ()
+gdbserver_windows_process::handle_unload_dll (const DEBUG_EVENT ¤t_event)
{
CORE_ADDR load_addr =
(CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
@@ -918,7 +914,7 @@ gdbserver_windows_process::handle_access_violation
PC. */
static void
-maybe_adjust_pc ()
+maybe_adjust_pc (const DEBUG_EVENT ¤t_event)
{
regcache *regcache = get_thread_regcache (current_thread);
child_fetch_inferior_registers (regcache, -1);
@@ -927,8 +923,8 @@ maybe_adjust_pc ()
= windows_process.find_thread (current_thread->id);
th->stopped_at_software_breakpoint = false;
- if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && (*the_low_target.is_sw_breakpoint) (&windows_process.current_event
+ if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
+ && (*the_low_target.is_sw_breakpoint) (¤t_event
.u.Exception.ExceptionRecord)
&& windows_process.child_initialization_done)
{
@@ -943,7 +939,8 @@ maybe_adjust_pc ()
static int
get_child_debug_event (DWORD *continue_status,
- struct target_waitstatus *ourstatus)
+ struct target_waitstatus *ourstatus,
+ DEBUG_EVENT *current_event)
{
ptid_t ptid;
@@ -954,8 +951,6 @@ get_child_debug_event (DWORD *continue_status,
/* Check if GDB sent us an interrupt request. */
check_remote_input_interrupt_request ();
- DEBUG_EVENT *current_event = &windows_process.current_event;
-
windows_process.attaching = 0;
{
process_info *proc = find_process_pid (windows_process.process_id);
@@ -968,8 +963,8 @@ get_child_debug_event (DWORD *continue_status,
{
*ourstatus = th->pending_stop.status;
th->pending_stop.status.set_ignore ();
- windows_process.current_event = th->pending_stop.event;
- ptid = debug_event_ptid (&windows_process.current_event);
+ *current_event = th->last_event;
+ ptid = debug_event_ptid (current_event);
switch_to_thread (find_thread_ptid (ptid));
return 1;
}
@@ -978,7 +973,7 @@ get_child_debug_event (DWORD *continue_status,
/* Keep the wait time low enough for comfortable remote
interruption, but high enough so gdbserver doesn't become a
bottleneck. */
- if (!wait_for_debug_event (&windows_process.current_event, 250))
+ if (!wait_for_debug_event (current_event, 250))
{
DWORD e = GetLastError();
@@ -1073,7 +1068,7 @@ get_child_debug_event (DWORD *continue_status,
CloseHandle (current_event->u.LoadDll.hFile);
if (! windows_process.child_initialization_done)
break;
- windows_process.dll_loaded_event ();
+ windows_process.dll_loaded_event (*current_event);
ourstatus->set_loaded ();
break;
@@ -1085,7 +1080,7 @@ get_child_debug_event (DWORD *continue_status,
(unsigned) current_event->dwThreadId));
if (! windows_process.child_initialization_done)
break;
- windows_process.handle_unload_dll ();
+ windows_process.handle_unload_dll (*current_event);
ourstatus->set_loaded ();
break;
@@ -1094,7 +1089,8 @@ get_child_debug_event (DWORD *continue_status,
"for pid=%u tid=%x\n",
(unsigned) current_event->dwProcessId,
(unsigned) current_event->dwThreadId));
- if (windows_process.handle_exception (ourstatus, debug_threads)
+ if (windows_process.handle_exception (*current_event,
+ ourstatus, debug_threads)
== HANDLE_EXCEPTION_UNHANDLED)
*continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
@@ -1105,7 +1101,7 @@ get_child_debug_event (DWORD *continue_status,
"for pid=%u tid=%x\n",
(unsigned) current_event->dwProcessId,
(unsigned) current_event->dwThreadId));
- windows_process.handle_output_debug_string (nullptr);
+ windows_process.handle_output_debug_string (*current_event, nullptr);
break;
default:
@@ -1117,10 +1113,12 @@ get_child_debug_event (DWORD *continue_status,
break;
}
- ptid = debug_event_ptid (&windows_process.current_event);
+ ptid = debug_event_ptid (current_event);
windows_thread_info *th = windows_process.find_thread (ptid);
+ th->last_event = *current_event;
+
if (th != nullptr && th->suspended)
{
/* Pending stop. See the comment by the definition of
@@ -1129,9 +1127,8 @@ get_child_debug_event (DWORD *continue_status,
OUTMSG2 (("get_windows_debug_event - "
"unexpected stop in suspended thread 0x%x\n",
th->tid));
- maybe_adjust_pc ();
+ maybe_adjust_pc (*current_event);
th->pending_stop.status = *ourstatus;
- th->pending_stop.event = *current_event;
ourstatus->set_spurious ();
}
else
@@ -1155,13 +1152,16 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
fails). Report it now. */
*ourstatus = windows_process.cached_status;
windows_process.cached_status.set_ignore ();
- return debug_event_ptid (&windows_process.current_event);
+ return ptid_t (windows_process.process_id,
+ windows_process.main_thread_id, 0);
}
while (1)
{
DWORD continue_status;
- if (!get_child_debug_event (&continue_status, ourstatus))
+ DEBUG_EVENT current_event;
+ if (!get_child_debug_event (&continue_status, ourstatus,
+ ¤t_event))
continue;
switch (ourstatus->kind ())
@@ -1170,20 +1170,20 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
OUTMSG2 (("Child exited with retcode = %x\n",
ourstatus->exit_status ()));
win32_clear_process ();
- return ptid_t (windows_process.current_event.dwProcessId);
+ return ptid_t (windows_process.process_id);
case TARGET_WAITKIND_STOPPED:
case TARGET_WAITKIND_SIGNALLED:
case TARGET_WAITKIND_LOADED:
{
OUTMSG2 (("Child Stopped with signal = %d \n",
ourstatus->sig ()));
- maybe_adjust_pc ();
+ maybe_adjust_pc (current_event);
/* All-stop, suspend all threads until they are explicitly
resumed. */
for_each_thread (suspend_one_thread);
- return debug_event_ptid (&windows_process.current_event);
+ return debug_event_ptid (¤t_event);
}
default:
OUTMSG (("Ignoring unknown internal event, %d\n",
diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h
index 9c672bfce1a..01a904043eb 100644
--- a/gdbserver/win32-low.h
+++ b/gdbserver/win32-low.h
@@ -179,9 +179,10 @@ class win32_process_target : public process_stratum_target
struct gdbserver_windows_process : public windows_nat::windows_process_info
{
windows_nat::windows_thread_info *find_thread (ptid_t ptid) override;
- DWORD handle_output_debug_string (struct target_waitstatus *ourstatus) override;
+ DWORD handle_output_debug_string (const DEBUG_EVENT ¤t_event,
+ struct target_waitstatus *ourstatus) override;
void handle_load_dll (const char *dll_name, LPVOID base) override;
- void handle_unload_dll () override;
+ void handle_unload_dll (const DEBUG_EVENT ¤t_event) override;
bool handle_access_violation (const EXCEPTION_RECORD *rec) override;
int attaching = 0;
--
2.53.0
next prev parent reply other threads:[~2026-04-24 20:48 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 20:44 [pushed 00/28] Windows non-stop prep Pedro Alves
2026-04-24 20:44 ` [pushed 01/28] Windows gdb+gdbserver: New find_thread, replaces thread_rec(DONT_INVALIDATE_CONTEXT) Pedro Alves
2026-04-24 20:44 ` [pushed 02/28] Windows gdb: handle_output_debug_string return type Pedro Alves
2026-04-24 20:44 ` [pushed 03/28] Windows gdb: Eliminate reload_context Pedro Alves
2026-04-24 20:44 ` [pushed 04/28] Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls Pedro Alves
2026-04-24 20:44 ` [pushed 05/28] Windows gdb+gdbserver: Eliminate DONT_SUSPEND Pedro Alves
2026-04-24 20:44 ` [pushed 06/28] Windows gdb+gdbserver: Eliminate windows_process_info::thread_rec Pedro Alves
2026-04-24 20:44 ` [pushed 07/28] Windows gdb: Simplify windows_nat_target::wait Pedro Alves
2026-04-26 12:52 ` Hannes Domani
2026-04-27 12:09 ` [pushed/ob] Restore windows_nat_target::wait is_sw_breakpoint change Pedro Alves
2026-04-24 20:44 ` [pushed 08/28] Windows gdb+gdbserver: Move suspending thread to when returning event Pedro Alves
2026-04-24 20:44 ` [pushed 09/28] Windows gdb: Introduce continue_last_debug_event_main_thread Pedro Alves
2026-04-24 20:44 ` [pushed 10/28] Windows gdb: Introduce windows_continue_flags Pedro Alves
2026-04-24 20:44 ` [pushed 11/28] Windows gdb: Factor code out of windows_nat_target::windows_continue Pedro Alves
2026-04-24 20:44 ` [pushed 12/28] Windows gdb: Pending stop and current_event Pedro Alves
2026-04-24 20:44 ` [pushed 13/28] Windows gdb+gdbserver: Elim desired_stop_thread_id / rework pending_stops Pedro Alves
2026-04-24 20:44 ` [pushed 14/28] Windows gdb+gdbserver: Introduce get_last_debug_event_ptid Pedro Alves
2026-04-24 20:44 ` [pushed 15/28] Windows gdb: Can't pass signal to thread other than last stopped thread Pedro Alves
2026-04-24 20:44 ` [pushed 16/28] Windows gdbserver: Fix scheduler-locking Pedro Alves
2026-04-24 20:44 ` [pushed 17/28] Windows gdb: Enable "set scheduler-locking on" Pedro Alves
2026-04-27 12:57 ` [pushed] Mention Windows scheduler-locking in NEWS (Re: [pushed 17/28] Windows gdb: Enable "set scheduler-locking on") Pedro Alves
2026-04-24 20:44 ` [pushed 18/28] Windows gdbserver: Eliminate soft-interrupt mechanism Pedro Alves
2026-04-24 20:44 ` Pedro Alves [this message]
2026-04-24 20:45 ` [pushed 20/28] Windows gdb+gdbserver: Make last_sig per-thread state Pedro Alves
2026-04-24 20:45 ` [pushed 21/28] Windows gdb+gdbserver: Make siginfo_er " Pedro Alves
2026-04-24 20:45 ` [pushed 22/28] Add backpointer from windows_thread_info to windows_process_info Pedro Alves
2026-04-24 20:45 ` [pushed 23/28] Windows gdb+gdbserver: Share $_siginfo reading code Pedro Alves
2026-04-24 20:45 ` [pushed 24/28] Windows gdb+gdbserver: Eliminate struct pending_stop Pedro Alves
2026-04-24 20:45 ` [pushed 25/28] Windows gdb: Change serial_event management Pedro Alves
2026-04-24 20:45 ` [pushed 26/28] Windows gdb: cygwin_set_dr => windows_set_dr, etc Pedro Alves
2026-04-24 20:45 ` [pushed 27/28] Windows gdb: Move debug macros to windows-nat.h Pedro Alves
2026-04-24 20:45 ` [pushed 28/28] Windows gdb: Avoid writing debug registers if watchpoint hit pending Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260424204508.1343973-20-pedro@palves.net \
--to=pedro@palves.net \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox