]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Windows GDB: Avoid hang second attach (gdb.base/attach.exp) (depends on non-stop...
authorPedro Alves <pedro@palves.net>
Fri, 2 Jun 2023 22:08:49 +0000 (23:08 +0100)
committerPedro Alves <pedro@palves.net>
Mon, 9 Jun 2025 17:49:19 +0000 (18:49 +0100)
[Before the non-stop series, there is no 'windows_process.process_id' field.]

gdb.base/attach.exp starts a second inferior and tries to attach the
second inferior to the same process that inferior 1 is already
debugging.  The point is to make sure that the backend errors out when
it tries to attach to a process that is already being debugged.

windows_nat_target::attach and windows_nat_target::create_inferior
both hang in this situation, because they call into do_synchronously,
which hangs because the 'process_thread' thread is blocked in
WaitForDebugEvent.

Until the Windows backend is taught to debug multiple processes, which
will require having one process_thread thread per inferior, detect the
situation and error out before GDB hangs.

Change-Id: I55b4438795439673c49fa55f55ddf0191f4f0ea8

gdb/windows-nat.c

index 0dab5fcf6daaa5049407c4f2b926a329630a514b..406a491a3bfb22f6ab184b2482d65c4d8ced4e90 100644 (file)
@@ -2780,14 +2780,24 @@ out:
   return ret;
 }
 
+/* Throw an error if we're already debugging a Windows process.  We
+   can only debug one at a time currently.  */
+
+static void
+ensure_only_one_process ()
+{
+  if (windows_process.process_id != 0)
+    error (_("Can only debug one process at a time."));
+}
+
 /* Attach to process PID, then initialize for debugging it.  */
 
 void
 windows_nat_target::attach (const char *args, int from_tty)
 {
-  DWORD pid;
+  ensure_only_one_process ();
 
-  pid = parse_pid_to_attach (args);
+  DWORD pid = parse_pid_to_attach (args);
 
   if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
     warning ("Failed to get SE_DEBUG_NAME privilege\n"
@@ -3140,6 +3150,8 @@ windows_nat_target::detach (inferior *inf, int from_tty)
   switch_to_no_thread ();
   detach_inferior (inf);
 
+  windows_process.process_id = 0;
+
   maybe_unpush_target ();
 }
 
@@ -3582,6 +3594,8 @@ windows_nat_target::create_inferior (const char *exec_file,
   DWORD flags = 0;
   const std::string &inferior_tty = current_inferior ()->tty ();
 
+  ensure_only_one_process ();
+
   if (!exec_file)
     error (_("No executable specified, use `target exec'."));
 
@@ -3891,6 +3905,7 @@ windows_nat_target::mourn_inferior ()
       CHECK (CloseHandle (windows_process.handle));
       windows_process.open_process_used = 0;
     }
+  windows_process.process_id = 0;
   inf_child_target::mourn_inferior ();
 }