From: Pedro Alves Date: Mon, 8 May 2023 20:36:28 +0000 (+0100) Subject: Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ee6ed94db97ab69667ed2827c58d85d80e5f0ee;p=thirdparty%2Fbinutils-gdb.git Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls Replace thread_rec(INVALIDATE_CONTEXT) calls with find_thread, and invalidate_context / suspend calls in the spots that might need those. I don't know why does the INVALIDATE_CONTEXT implementation in GDB avoid suspending the event thread: case INVALIDATE_CONTEXT: if (ptid.lwp () != current_event.dwThreadId) th->suspend (); Checks for a global "current_event" get in the way of non-stop support later in the series, as each thread will have its own "last debug event". Regardless, it should be fine to suspend the event thread. As a data point, the GDBserver implementation always suspends. So this patch does not try to avoid suspending the event thread on the native side either. Approved-By: Tom Tromey Change-Id: I8d2f0a749d23329956e62362a7007189902dddb5 --- diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index 71560930e84..f7f2f3e62a7 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -109,8 +109,6 @@ enum thread_disposition_type { /* Invalidate the context, but do not suspend the thread. */ DONT_SUSPEND, - /* Invalidate the context and suspend the thread. */ - INVALIDATE_CONTEXT }; /* A single pending stop. See "pending_stops" for more diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 21835dbff15..21239f6dea0 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -545,11 +545,6 @@ windows_per_inferior::thread_rec (ptid_t ptid, { switch (disposition) { - case INVALIDATE_CONTEXT: - if (ptid.lwp () != current_event.dwThreadId) - th->suspend (); - invalidate_context (th); - break; case DONT_SUSPEND: th->suspended = -1; invalidate_context (th); @@ -721,8 +716,7 @@ windows_fetch_one_register (struct regcache *regcache, void windows_nat_target::fetch_registers (struct regcache *regcache, int r) { - windows_thread_info *th - = windows_process.thread_rec (regcache->ptid (), INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (regcache->ptid ()); /* Check if TH exists. Windows sometimes uses a non-existent thread id in its events. */ @@ -733,6 +727,7 @@ windows_nat_target::fetch_registers (struct regcache *regcache, int r) { if (context->ContextFlags == 0) { + th->suspend (); context->ContextFlags = WindowsContext::all; CHECK (get_thread_context (th->h, context)); } @@ -759,6 +754,7 @@ windows_store_one_register (const struct regcache *regcache, char *context_ptr = windows_process.with_context (th, [] (auto *context) { + gdb_assert (context->ContextFlags != 0); return (char *) context; }); @@ -793,8 +789,7 @@ windows_store_one_register (const struct regcache *regcache, void windows_nat_target::store_registers (struct regcache *regcache, int r) { - windows_thread_info *th - = windows_process.thread_rec (regcache->ptid (), INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (regcache->ptid ()); /* Check if TH exists. Windows sometimes uses a non-existent thread id in its events. */ @@ -1456,7 +1451,9 @@ windows_nat_target::get_windows_debug_event *ourstatus = stop->status; ptid_t ptid (windows_process.current_event.dwProcessId, thread_id); - windows_process.thread_rec (ptid, INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (ptid); + if (th != nullptr) + windows_process.invalidate_context (th); return ptid; } @@ -1677,8 +1674,7 @@ windows_nat_target::get_windows_debug_event && windows_process.windows_initialization_done) { ptid_t ptid = ptid_t (current_event->dwProcessId, thread_id, 0); - windows_thread_info *th - = windows_process.thread_rec (ptid, INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (ptid); th->stopped_at_software_breakpoint = true; th->pc_adjusted = false; } @@ -1716,8 +1712,7 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, if (ourstatus->kind () != TARGET_WAITKIND_EXITED && ourstatus->kind () != TARGET_WAITKIND_SIGNALLED) { - windows_thread_info *th - = windows_process.thread_rec (result, INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (result); if (th != nullptr) { diff --git a/gdbserver/win32-low.cc b/gdbserver/win32-low.cc index 2bf42f42350..42026971037 100644 --- a/gdbserver/win32-low.cc +++ b/gdbserver/win32-low.cc @@ -443,9 +443,8 @@ static void child_fetch_inferior_registers (struct regcache *regcache, int r) { int regno; - windows_thread_info *th - = windows_process.thread_rec (current_thread->id, - INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (current_thread->id); + win32_require_context (th); if (r == -1 || r > NUM_REGS) child_fetch_inferior_registers (regcache, NUM_REGS); else @@ -459,9 +458,8 @@ static void child_store_inferior_registers (struct regcache *regcache, int r) { int regno; - windows_thread_info *th - = windows_process.thread_rec (current_thread->id, - INVALIDATE_CONTEXT); + windows_thread_info *th = windows_process.find_thread (current_thread->id); + win32_require_context (th); if (r == -1 || r == 0 || r > NUM_REGS) child_store_inferior_registers (regcache, NUM_REGS); else