]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls
authorPedro Alves <pedro@palves.net>
Mon, 8 May 2023 20:36:28 +0000 (21:36 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 17:09:12 +0000 (18:09 +0100)
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 <tom@tromey.com>
Change-Id: I8d2f0a749d23329956e62362a7007189902dddb5

gdb/nat/windows-nat.h
gdb/windows-nat.c
gdbserver/win32-low.cc

index 71560930e845dcc8a958c6e28f3d22c70ef5d71b..f7f2f3e62a70eee617b9c9efff0a264ec39ed5e0 100644 (file)
@@ -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
index 21835dbff154fef6aa5fa1c8e65ebcd5c397dd40..21239f6dea0b649c9a2f921a2c61185bdb436380 100644 (file)
@@ -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<decltype(context)>::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)
                {
index 2bf42f42350c0102ea9e3a4f90cf82ff901fb7b1..4202697103700a16b694ad74a149f244f0e1f746 100644 (file)
@@ -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