]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Windows gdb+gdbserver: Move suspending thread to when returning event
authorPedro Alves <pedro@palves.net>
Tue, 9 May 2023 09:27:04 +0000 (10:27 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 17:09:12 +0000 (18:09 +0100)
The current code suspends a thread just before calling
GetThreadContext.  You can only call GetThreadContext if the thread is
suspended.  But, after WaitForDebugEvent, all threads are implicitly
suspended.  So I don't think we even needed to call SuspendThread
explictly at all before our GetThreadContext calls.

However, suspending threads when we're about to present a stop to gdb
simplifies adding non-stop support later.  This way, the windows
SuspendThread state corresponds to whether a thread is suspended or
resumed from the core's perspective.  Curiously, I noticed that Wine's
winedbg does something similar:
https://github.com/wine-mirror/wine/blob/234943344f7495d1e072338f0e06fa2d5cbf0aa1/programs/winedbg/gdbproxy.c#L651

This makes it much easier to reason about a thread's suspend state,
and simplifies adding non-stop mode later on.

Change-Id: Ifd6889a8afc041fad33cd1c4500e38941da6781b

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

index f1ec8837e8273582004b4f09f443798151fb065a..a81a7eebfe95b2ffb7ccf0f11f3a4280e6771f3a 100644 (file)
@@ -706,7 +706,6 @@ 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));
         }
@@ -1233,12 +1232,6 @@ windows_nat_target::windows_continue (DWORD continue_status, int id,
 
        th->resume ();
       }
-    else
-      {
-       /* When single-stepping a specific thread, other threads must
-          be suspended.  */
-       th->suspend ();
-      }
 
   std::optional<unsigned> err;
   do_synchronously ([&] ()
@@ -1717,6 +1710,11 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
                  th->stopped_at_software_breakpoint = true;
                  th->pc_adjusted = false;
                }
+
+             /* All-stop, suspend all threads until they are
+                explicitly resumed.  */
+             for (auto &thr : windows_process.thread_list)
+               thr->suspend ();
            }
 
          return result;
index c99248d37cb4cce03849fa9294f6dcf418da5037..a23a41b9c024c0d90f48a0615dc8548a84152c69 100644 (file)
@@ -1194,6 +1194,11 @@ win32_process_target::wait (ptid_t ptid, target_waitstatus *ourstatus,
            OUTMSG2 (("Child Stopped with signal = %d \n",
                      ourstatus->sig ()));
            maybe_adjust_pc ();
+
+           /* All-stop, suspend all threads until they are explicitly
+              resumed.  */
+           for_each_thread (suspend_one_thread);
+
            return debug_event_ptid (&windows_process.current_event);
          }
        default: