From: Pedro Alves <pedro@palves.net>
To: gdb-patches@sourceware.org
Subject: [PATCH] Windows gdb: Avoid hang second attach/run
Date: Tue, 5 May 2026 13:18:23 +0100 [thread overview]
Message-ID: <20260505121823.1442331-1-pedro@palves.net> (raw)
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.
E.g.:
attach 4420
FAIL: gdb.base/attach.exp: do_attach_failure_tests: fail to attach again (timeout)
Until the Windows backend is taught to debug multiple processes, which
will probably require having one process_thread thread per inferior,
detect the situation and error out before GDB hangs.
This results in the following progression in gdb.base/attach.exp:
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: fail to attach again (timeout)
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: set confirm off (timeout)
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 1 (timeout)
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: exit after attach failures (timeout)
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: gdb_breakpoint: set breakpoint at main (timeout)
-FAIL: gdb.base/attach.exp: do_attach_failure_tests: stop at main (timeout)
+PASS: gdb.base/attach.exp: do_attach_failure_tests: fail to attach again
+PASS: gdb.base/attach.exp: do_attach_failure_tests: set confirm off
+PASS: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 1
+PASS: gdb.base/attach.exp: do_attach_failure_tests: exit after attach failures
+PASS: gdb.base/attach.exp: do_attach_failure_tests: stop at main
There are still other failures not addressed by this patch.
Tests that launch a second program with "run" exist, but are normally
gated by allow_multi_inferior_tests.
Change-Id: I55b4438795439673c49fa55f55ddf0191f4f0ea8
commit-id: 1caa5be0
---
gdb/testsuite/gdb.base/attach.exp | 4 ++++
gdb/windows-nat.c | 19 +++++++++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index bffdfd9b1aa..a4e7d72ef94 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -175,6 +175,10 @@ proc_with_prefix do_attach_failure_tests {} {
# Response expected when using gdbserver.
pass "$test"
}
+ -re -wrap "Can only debug one process at a time\\." {
+ # Response expected on Windows.
+ pass "$test"
+ }
}
# To ensure the target is still alive and working after this, try to run
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index a9647e90bb8..6b2a5d30132 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -2010,14 +2010,24 @@ set_process_privilege (const char *privilege, BOOL enable)
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"
@@ -2369,6 +2379,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 ();
}
@@ -2811,6 +2823,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'."));
@@ -3120,6 +3134,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 ();
}
base-commit: 8c0ac471835ec86a67c5b42713d9f138f31e4014
--
2.53.0
next reply other threads:[~2026-05-05 12:18 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-05 12:18 Pedro Alves [this message]
2026-05-05 14:05 ` Tom Tromey
2026-05-07 18:24 ` Pedro Alves
2026-05-08 12:24 ` Tom Tromey
2026-05-05 14:05 ` 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=20260505121823.1442331-1-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