From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH 21/34] Windows gdb+gdbserver: Make current_event per-thread state
Date: Wed, 8 May 2024 00:42:20 +0100 [thread overview]
Message-ID: <20240507234233.371123-22-pedro@palves.net> (raw)
In-Reply-To: <20240507234233.371123-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.
Change-Id: Ice09a5d932c912210608d5af25e1898f823e3c99
---
gdb/nat/windows-nat.c | 13 ++--
gdb/nat/windows-nat.h | 24 ++++----
gdb/windows-nat.c | 136 ++++++++++++++++++++++-------------------
gdbserver/win32-low.cc | 70 ++++++++++-----------
gdbserver/win32-low.h | 5 +-
5 files changed, 129 insertions(+), 119 deletions(-)
diff --git a/gdb/nat/windows-nat.c b/gdb/nat/windows-nat.c
index 7f8834facd4..cabc61fb2d2 100644
--- a/gdb/nat/windows-nat.c
+++ b/gdb/nat/windows-nat.c
@@ -310,8 +310,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)
{
@@ -352,7 +354,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) \
@@ -480,7 +483,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;
@@ -634,11 +637,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 70912fd6210..73c828ec2c9 100644
--- a/gdb/nat/windows-nat.h
+++ b/gdb/nat/windows-nat.h
@@ -40,10 +40,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;
};
@@ -98,6 +94,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
{
@@ -143,10 +143,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 {};
@@ -170,7 +166,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.
@@ -191,7 +188,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".
@@ -201,11 +198,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. */
@@ -222,7 +220,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 5ebf53e2816..1a01ae57e54 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -107,9 +107,10 @@ DEF_ENUM_FLAGS_TYPE (windows_continue_flag, windows_continue_flags);
struct windows_per_inferior : public 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;
void invalidate_context (windows_thread_info *th);
@@ -321,7 +322,8 @@ struct windows_nat_target final : public x86_nat_target<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);
@@ -352,7 +354,7 @@ struct windows_nat_target final : public x86_nat_target<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);
BOOL windows_continue (DWORD continue_status, int id,
windows_continue_flags cont_flags = 0);
@@ -979,7 +981,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;
@@ -1042,7 +1044,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;
@@ -1387,11 +1390,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
@@ -1400,12 +1403,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
@@ -1422,6 +1424,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
@@ -1434,8 +1443,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);
@@ -1452,7 +1460,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;
@@ -1469,36 +1477,28 @@ 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)
- {
#ifdef __x86_64__
- if (windows_process.wow64_process)
+ if (windows_process.wow64_process)
+ {
+ if (step)
{
- if (step)
- {
- /* Single step by setting t bit. */
- regcache *regcache = get_thread_regcache (inferior_thread ());
- struct gdbarch *gdbarch = regcache->arch ();
- fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
- th->wow64_context.EFlags |= FLAG_TRACE_BIT;
- }
+ /* Single step by setting t bit. */
+ regcache *regcache = get_thread_regcache (inferior_thread ());
+ struct gdbarch *gdbarch = regcache->arch ();
+ fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
+ th->wow64_context.EFlags |= FLAG_TRACE_BIT;
}
- else
+ }
+ else
#endif
+ {
+ if (step)
{
- if (step)
- {
- /* Single step by setting t bit. */
- regcache *regcache = get_thread_regcache (inferior_thread ());
- struct gdbarch *gdbarch = regcache->arch ();
- fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
- th->context.EFlags |= FLAG_TRACE_BIT;
- }
+ /* Single step by setting t bit. */
+ regcache *regcache = get_thread_regcache (inferior_thread ());
+ struct gdbarch *gdbarch = regcache->arch ();
+ fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
+ th->context.EFlags |= FLAG_TRACE_BIT;
}
}
@@ -1562,7 +1562,8 @@ windows_nat_target::pass_ctrlc ()
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;
@@ -1580,7 +1581,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_context (th.get ());
@@ -1589,7 +1590,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)
{
@@ -1597,11 +1597,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)
@@ -1619,7 +1619,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++;
}
@@ -1716,7 +1716,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)
{
@@ -1736,7 +1736,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)
{
@@ -1753,7 +1753,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:
@@ -1775,7 +1776,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:
@@ -1800,6 +1802,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
@@ -1818,8 +1822,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
@@ -1845,7 +1849,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)
@@ -1864,11 +1871,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)
{
@@ -1909,8 +1916,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);
@@ -1957,7 +1962,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));
@@ -2233,7 +2241,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);
@@ -2244,7 +2252,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);
}
@@ -3041,9 +3049,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/gdbserver/win32-low.cc b/gdbserver/win32-low.cc
index 99a6150599e..5608fb902b1 100644
--- a/gdbserver/win32-low.cc
+++ b/gdbserver/win32-low.cc
@@ -309,9 +309,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))
@@ -622,7 +619,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;
@@ -691,14 +689,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_inferiors ();
@@ -772,8 +769,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",
@@ -918,7 +914,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;
@@ -952,7 +948,7 @@ gdbserver_windows_process::handle_access_violation
PC. */
static void
-maybe_adjust_pc ()
+maybe_adjust_pc (const DEBUG_EVENT ¤t_event)
{
struct regcache *regcache = get_thread_regcache (current_thread, 1);
child_fetch_inferior_registers (regcache, -1);
@@ -961,10 +957,10 @@ maybe_adjust_pc ()
= windows_process.find_thread (current_thread_ptid ());
th->stopped_at_software_breakpoint = false;
- if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
+ if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
+ && ((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.child_initialization_done)
{
@@ -979,7 +975,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;
@@ -990,8 +987,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;
{
for (thread_info *thread : all_threads)
@@ -1003,8 +998,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;
}
@@ -1013,7 +1008,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();
@@ -1108,7 +1103,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;
@@ -1120,7 +1115,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;
@@ -1129,7 +1124,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;
@@ -1140,7 +1136,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:
@@ -1152,10 +1148,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
@@ -1164,9 +1162,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
@@ -1190,13 +1187,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 ())
@@ -1205,20 +1205,20 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
OUTMSG2 (("Child exited with retcode = %x\n",
ourstatus->exit_status ()));
win32_clear_inferiors ();
- 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 4d26b87d73d..e99e47ea829 100644
--- a/gdbserver/win32-low.h
+++ b/gdbserver/win32-low.h
@@ -175,9 +175,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.43.2
next prev parent reply other threads:[~2024-05-07 23:44 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-07 23:41 [PATCH 00/34] Windows non-stop mode Pedro Alves
2024-05-07 23:42 ` [PATCH 01/34] Windows gdb: Dead code in windows_nat_target::do_initial_windows_stuff Pedro Alves
2024-05-08 14:39 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 02/34] Windows gdb: Eliminate global current_process.dr[8] global Pedro Alves
2024-05-08 15:02 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 03/34] Windows gdb+gdbserver: New find_thread, replaces thread_rec(DONT_INVALIDATE_CONTEXT) Pedro Alves
2024-05-08 15:03 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 04/34] Windows gdb: handle_output_debug_string return type Pedro Alves
2024-05-08 14:43 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 05/34] Windows gdb: Eliminate reload_context Pedro Alves
2024-05-08 14:45 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 06/34] Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls Pedro Alves
2024-05-08 15:08 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 07/34] Windows gdb+gdbserver: Eliminate DONT_SUSPEND Pedro Alves
2024-05-08 15:12 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 08/34] Windows gdb+gdbserver: Eliminate windows_process_info::thread_rec Pedro Alves
2024-05-08 15:12 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 09/34] Windows gdb: Simplify windows_nat_target::wait Pedro Alves
2024-05-07 23:42 ` [PATCH 10/34] Windows gdb+gdbserver: Move suspending thread to when returning event Pedro Alves
2024-05-07 23:42 ` [PATCH 11/34] Windows gdb: Introduce continue_last_debug_event_main_thread Pedro Alves
2024-05-08 14:53 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 12/34] Windows gdb: Introduce windows_continue_flags Pedro Alves
2024-05-08 15:16 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 13/34] Windows gdb: Factor code out of windows_nat_target::windows_continue Pedro Alves
2024-05-08 15:18 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 14/34] Windows gdb: Pending stop and current_event Pedro Alves
2024-05-08 15:18 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 15/34] Windows gdb+gdbserver: Elim desired_stop_thread_id / rework pending_stops Pedro Alves
2024-05-07 23:42 ` [PATCH 16/34] Windows gdb+gdbserver: Introduce get_last_debug_event_ptid Pedro Alves
2024-05-07 23:42 ` [PATCH 17/34] Windows gdb: Can't pass signal to thread other than last stopped thread Pedro Alves
2024-05-07 23:42 ` [PATCH 18/34] Windows gdbserver: Fix scheduler-locking Pedro Alves
2024-05-07 23:42 ` [PATCH 19/34] Windows gdb: Enable "set scheduler-locking on" Pedro Alves
2024-05-08 15:25 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 20/34] Windows gdbserver: Eliminate soft-interrupt mechanism Pedro Alves
2024-05-08 15:26 ` Tom Tromey
2024-05-07 23:42 ` Pedro Alves [this message]
2024-05-07 23:42 ` [PATCH 22/34] Windows gdb+gdbserver: Make last_sig per-thread state Pedro Alves
2024-05-07 23:42 ` [PATCH 23/34] Windows gdb+gdbserver: Make siginfo_er " Pedro Alves
2024-05-07 23:42 ` [PATCH 24/34] Add backpointer from windows_thread_info to windows_process_info Pedro Alves
2024-05-08 15:28 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 25/34] Windows gdb+gdbserver: Share $_siginfo reading code Pedro Alves
2024-05-08 15:29 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 26/34] Windows gdb+gdbserver: Eliminate struct pending_stop Pedro Alves
2024-05-07 23:42 ` [PATCH 27/34] Windows gdb: Change serial_event management Pedro Alves
2024-05-07 23:42 ` [PATCH 28/34] Windows gdb: cygwin_set_dr => windows_set_dr, etc Pedro Alves
2024-05-08 14:46 ` Tom Tromey
2024-05-07 23:42 ` [PATCH 29/34] windows_per_inferior::continue_one_thread, unify WoW64/non-WoW64 paths Pedro Alves
2024-05-07 23:42 ` [PATCH 30/34] windows-nat.c: Avoid writing debug registers if watchpoint hit pending Pedro Alves
2024-05-07 23:42 ` [PATCH 31/34] Windows gdb+gdbserver: Check whether DBG_REPLY_LATER is available Pedro Alves
2024-05-08 12:45 ` Eli Zaretskii
2024-05-08 21:33 ` [PATCH 31/34 v1.2] " Pedro Alves
2024-05-09 10:07 ` Hannes Domani
[not found] ` <86zfsz5kly.fsf@gnu.org>
2024-05-09 11:11 ` Pedro Alves
2024-05-09 11:47 ` [PATCH 31/34 v1.3] " Pedro Alves
2024-05-09 12:28 ` Eli Zaretskii
2024-05-09 14:17 ` Tom Tromey
[not found] ` <86r0eb5g2n.fsf@gnu.org>
2024-05-09 13:27 ` [PATCH 31/34 v1.2] " Pedro Alves
2024-05-07 23:42 ` [PATCH 32/34] Windows gdb: Add non-stop support Pedro Alves
2024-05-07 23:42 ` [PATCH 33/34] Windows gdb: Watchpoints while running (internal vs external stops) Pedro Alves
2024-05-07 23:42 ` [PATCH 34/34] Mention Windows non-stop support in NEWS Pedro Alves
2024-05-08 15:40 ` [PATCH 00/34] Windows non-stop mode Tom Tromey
2024-05-15 17:35 ` Tom Tromey
2024-05-15 20:39 ` Pedro Alves
2024-05-16 15:53 ` Tom Tromey
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=20240507234233.371123-22-pedro@palves.net \
--to=pedro@palves.net \
--cc=gdb-patches@sourceware.org \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).