Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@palves.net>
To: Tom Tromey <tromey@adacore.com>
Cc: gdb-patches@sourceware.org
Subject: [PATCH] Improve attach on Windows (was: Re: [PATCH v2 00/47] Windows non-stop mode)
Date: Wed, 11 Jun 2025 23:06:48 +0100	[thread overview]
Message-ID: <becd6119-3b7a-414e-87d3-c449d2f4095d@palves.net> (raw)
In-Reply-To: <87ldq6ax6c.fsf@tromey.com>

Hi!

On 2025-06-05 18:57, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <pedro@palves.net> writes:
> 
> Pedro> I've pushed the series to the users/palves/windows-non-stop-v2 branch
> Pedro> on sourceware.org, for your convenience.
> 
> I merged this into the local tree and ran the internal AdaCore test
> suite on Windows 2016.

Thank you very much for doing this.  Much appreciated.

> 
> There were three "failures".
> 
> One of them is actually an improvement, where the test works around a
> current issue.
> 

One step forward, two steps back, I guess.

Tackling this incrementally.  I've looked at the first one:

> One of them seems to be a problem with the test.  This test "attach"es
> to a running process without a "file", and the test doesn't seem to
> match the new output:
> 
>     (gdb) attach 1228
>     Attaching to process 1228
>     [Switching to Thread 1228.0x580]
>     0x00007ffe3c756714 in ntdll!ZwDelayExecution ()
>        from C:\Windows\SYSTEM32\ntdll.dll
> 

I guess your test wasn't expecting that the current frame is printed?

See the patch below, on top of current master.  You are now seeing the current
frame being printed, unlike what I claim in the commit log of the patch below,
because with target-non-stop on, the Windows backend is a target_wait_no_wait==false
target, like Linux.

But even with the non-stop series, with "maint set target-non-stop off",
(or with Windows older than Windows 10,) then target_wait_no_wait==true, and
GDB doesn't print the frame.

IMO, this is just a preexisting bug that the non-stop series happens to hide.

Let me know what you think of the patch.

And yes, the fact that run control communicates with normal_stop via
globals is ugly and fragile to say the least.

From 0cb83571c91ba42b3de519b034509092a526dc65 Mon Sep 17 00:00:00 2001
From: Pedro Alves <pedro@palves.net>
Date: Wed, 11 Jun 2025 22:05:23 +0100
Subject: [PATCH] Improve attach on Windows

Unlike most targets, on Windows, when you attach, GDB doesn't print
the current stack frame.  Vis:

On GNU/Linux:

 attach 3340347
 Attaching to program: /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.base/attach/attach, process 3340347
 Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
 Reading symbols from /usr/lib/debug/.build-id/d5/197096f709801829b118af1b7cf6631efa2dcd.debug...
 Reading symbols from /lib64/ld-linux-x86-64.so.2...
 Reading symbols from /usr/lib/debug/.build-id/9c/b53985768bb99f138f48655f7b8bf7e420d13d.debug...
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 0x00005b3bf29be174 in main () at /home/pedro/gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.base/attach.c:19
 19        while (! should_exit)
 (gdb) PASS: gdb.base/attach.exp: do_attach_tests: attach1, after setting file

On Cygwin:

 (gdb) attach 6692
 Attaching to program: /home/alves/gdb/build-cygwin-testsuite/outputs/gdb.base/attach/attach, process 6692
 [New Thread 6692.0x2e60]
 [New Thread 6692.0x2e9c]
 [New Thread 6692.0xd6c]
 [New Thread 6692.0x137c]
 [New Thread 6692.0x1270]
 (gdb) FAIL: gdb.base/attach.exp: do_attach_tests: attach1, after setting file

On Linux, GDB prints the frame because after the target_attach, GDB
goes back to the event loop, to wait for an initial stop event.  The
stop event arrives, and we process it, which sets the stop_print_frame
global, and then we get to normal_stop, which prints the frame iff
stop_print_frame is set, which it is.

Windows OTOH, is a target_attach_no_wait target, so after
target_attach, there is no going back to event loop.  In
infcmd.c:attach_command, we go straight to attach_post_wait which
takes us to normal_stop.  But this time, nothing set
stop_print_frame to true, so no frame is printed.  Actually, if the
global happened to be true due to an earlier event from debugging a
previous inferior, then we will print the frame.

This patch makes GDB's behavior consistent, by making sure the globals
normal_stop looks at are in a good state in the target_attach_no_wait
path.

With that alone, GDB now prints the frame:

 (gdb) attach 2915
 Attaching to program: /usr/bin/sleep.exe, process 2832
 [New Thread 2832.0x2a68]
 [New Thread 2832.0xb1c]
 [New Thread 2832.0x8ac]
 [Switching to Thread 2832.0x8ac]
 0x00007ffec51d4a71 in ntdll!DbgBreakPoint () from C:/Windows/SYSTEM32/ntdll.dll

This is still not ideal, IMHO, as the current thread is the thread
that Windows injects to attach:

 (gdb) info threads
   Id   Target Id                  Frame
   1    Thread 2832.0x2100 "sleep" 0x00007ffec51d18d7 in ntdll!ZwWaitForMultipleObjects () from C:/Windows/SYSTEM32/ntdll.dll
   2    Thread 2832.0x2a68 "sig"   0x00007ffec51d0e47 in ntdll!ZwReadFile () from C:/Windows/SYSTEM32/ntdll.dll
   3    Thread 2832.0xb1c          0x00007ffec51d49d7 in ntdll!ZwWaitForWorkViaWorkerFactory () from C:/Windows/SYSTEM32/ntdll.dll
 * 4    Thread 2832.0x8ac          0x00007ffec51d4a71 in ntdll!DbgBreakPoint () from C:/Windows/SYSTEM32/ntdll.dll

Automatically switching to main thread is IMHO more useful.  That
results in very similar output than what we see on Linux:

 attach 5164
 Attaching to program: /home/alves/gdb/build-cygwin-testsuite/outputs/gdb.base/attach/attach, process 5164
 [New Thread 5164.0x87c]
 [New Thread 5164.0x28f0]
 [New Thread 5164.0x376c]
 [New Thread 5164.0x2db4]
 [New Thread 5164.0xce4]
 main () at /home/alves/gdb/src/gdb/testsuite/gdb.base/attach.c:19
 19        while (! should_exit)
 (gdb)

If we do this, then we can simplify gdb.base/attach.exp a bit by
removing a couple Cygwin special cases.

The patch does all that, which results in the following
gdb.base/attach.exp progressions:

 -FAIL: gdb.base/attach.exp: do_attach_tests: attach1, after setting file
 -FAIL: gdb.base/attach.exp: do_attach_tests: attach2, with no file
 -FAIL: gdb.base/attach.exp: do_attach_tests: load file manually, after attach2 (re-read) (got interactive prompt)
 -FAIL: gdb.base/attach.exp: do_attach_tests: attach when process' a.out not in cwd
 -FAIL: gdb.base/attach.exp: do_attach_failure_tests: first attach
 +PASS: gdb.base/attach.exp: do_attach_tests: attach1, after setting file
 +PASS: gdb.base/attach.exp: do_attach_tests: attach2, with no file
 +PASS: gdb.base/attach.exp: do_attach_tests: attach when process' a.out not in cwd
 +PASS: gdb.base/attach.exp: do_attach_failure_tests: first attach

Change-Id: I359bdb25660c9a4d5d873e8771cfd1cd2a54c97b
---
 gdb/infcmd.c                      |  5 ++++-
 gdb/infrun.c                      | 13 +++++++++++++
 gdb/infrun.h                      |  3 +++
 gdb/testsuite/gdb.base/attach.exp | 26 ++++++--------------------
 gdb/windows-nat.c                 |  7 +++++++
 5 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index e9b58ce5521..cbf2373193c 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2722,7 +2722,10 @@ attach_command (const char *args, int from_tty)
       return;
     }
   else
-    attach_post_wait (from_tty, mode);
+    {
+      set_normal_stop_state_just_attached ();
+      attach_post_wait (from_tty, mode);
+    }
 
   disable_commit_resumed.reset_and_commit ();
 }
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 2e02642c52a..41ab3342ee3 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -407,6 +407,19 @@ static process_stratum_target *target_last_proc_target;
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
+/* See infrun.h.  */
+
+void
+set_normal_stop_state_just_attached ()
+{
+  stop_print_frame = true;
+  stopped_by_random_signal = 0;
+
+  target_waitstatus status;
+  status.set_ignore ();
+  set_last_target_status (nullptr, minus_one_ptid, status);
+}
+
 void init_thread_stepping_state (struct thread_info *tss);
 
 static const char follow_fork_mode_child[] = "child";
diff --git a/gdb/infrun.h b/gdb/infrun.h
index b9b64aca45a..b707314fba6 100644
--- a/gdb/infrun.h
+++ b/gdb/infrun.h
@@ -418,5 +418,8 @@ struct scoped_enable_commit_resumed
   bool m_prev_enable_commit_resumed;
 };
 
+/* Set up state for normal_stop after we just attached, on
+   target_attach_no_wait targets.  */
+extern void set_normal_stop_state_just_attached ();
 
 #endif /* GDB_INFRUN_H */
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index 0d1550a0541..484fa776ae4 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -159,16 +159,9 @@ proc_with_prefix do_attach_failure_tests {} {
     
     # Verify that we can't double attach to the process.
 
-    set test "first attach"
-    gdb_test_multiple "attach $testpid" "$test" {
-	-re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $" {
-	    pass "$test"
-	}
-	-re "Attaching to program.*`?$escapedbinfile\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" {
-	    # Response expected on Cygwin.
-	    pass "$test"
-	}
-    }
+    gdb_test "attach $testpid" \
+	"Attaching to program.*`?${escapedbinfile}(\.exe)?'?, process $testpid.*main.*at .*$srcfile:.*" \
+	"first attach"
 
     gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
     gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2"
@@ -252,16 +245,9 @@ proc_with_prefix do_attach_tests {} {
 	}
     }
 
-    set test "attach1, after setting file"
-    gdb_test_multiple "attach $testpid" "$test" {
-	-re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $" {
-	    pass "$test"
-	}
-	-re "Attaching to program.*`?$escapedbinfile\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" {
-	    # Response expected on Cygwin
-	    pass "$test"
-	}
-    }
+    gdb_test "attach $testpid" \
+	"Attaching to program.*`?${escapedbinfile}(\.exe)?'?, process $testpid.*main.*at .*$srcfile:.*" \
+	"attach1, after setting file"
 
     # Verify that we can "see" the variable "should_exit" in the
     # program, and that it is zero.
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 939c5813aa7..0477731d40c 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1980,6 +1980,13 @@ windows_nat_target::attach (const char *args, int from_tty)
 #endif
 
   do_initial_windows_stuff (pid, 1);
+
+  /* The thread that reports the initial breakpoint, and thus ends up
+     as the selected thread when we get here, was injected into the
+     inferior by DebugActiveProcess.  Switch to the main thread, which
+     is normally more useful to the user than the injected thread.  */
+  switch_to_thread (first_thread_of_inferior (current_inferior ()));
+
   target_terminal::ours ();
 }
 

base-commit: eb6c9310ee4d6cbde509d251fafb54ae45f5a5bf
-- 
2.49.0



  reply	other threads:[~2025-06-11 22:07 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-19 13:22 [PATCH v2 00/47] Windows non-stop mode Pedro Alves
2025-05-19 13:22 ` [PATCH v2 01/47] Make default_gdb_exit resilient to failed closes Pedro Alves
2025-05-19 13:56   ` Andrew Burgess
2025-06-06 13:56     ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 02/47] Add test for continuing with some threads running Pedro Alves
2025-05-21 19:36   ` Kevin Buettner
2026-04-02 13:07     ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 03/47] infrun: Remove unnecessary currently_stepping call Pedro Alves
2025-05-21 19:44   ` Kevin Buettner
2026-04-02 13:17     ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 04/47] infrun: Split currently_stepping, fix sw watchpoints issue Pedro Alves
2026-04-02 13:33   ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 05/47] thread_info::executing+resumed -> thread_info::internal_state Pedro Alves
2026-04-06 18:01   ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 06/47] Windows gdb: Dead code in windows_nat_target::do_initial_windows_stuff Pedro Alves
2025-05-19 13:22 ` [PATCH v2 07/47] Windows gdb: Eliminate global current_process.dr[8] global Pedro Alves
2025-05-28 19:09   ` Tom Tromey
2026-04-06 19:44   ` Pedro Alves
2025-05-19 13:22 ` [PATCH v2 08/47] Windows gdb+gdbserver: New find_thread, replaces thread_rec(DONT_INVALIDATE_CONTEXT) Pedro Alves
2025-05-19 13:22 ` [PATCH v2 09/47] Windows gdb: handle_output_debug_string return type Pedro Alves
2025-05-19 13:22 ` [PATCH v2 10/47] Windows gdb: Eliminate reload_context Pedro Alves
2025-05-19 13:22 ` [PATCH v2 11/47] Windows gdb+gdbserver: Eliminate thread_rec(INVALIDATE_CONTEXT) calls Pedro Alves
2025-05-19 13:22 ` [PATCH v2 12/47] Windows gdb+gdbserver: Eliminate DONT_SUSPEND Pedro Alves
2025-05-19 13:22 ` [PATCH v2 13/47] Windows gdb+gdbserver: Eliminate windows_process_info::thread_rec Pedro Alves
2025-05-19 13:22 ` [PATCH v2 14/47] Windows gdb: Simplify windows_nat_target::wait Pedro Alves
2025-05-28 19:16   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 15/47] Windows gdb+gdbserver: Move suspending thread to when returning event Pedro Alves
2025-05-28 19:17   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 16/47] Windows gdb: Introduce continue_last_debug_event_main_thread Pedro Alves
2025-05-28 19:18   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 17/47] Windows gdb: Introduce windows_continue_flags Pedro Alves
2025-05-19 13:22 ` [PATCH v2 18/47] Windows gdb: Factor code out of windows_nat_target::windows_continue Pedro Alves
2025-05-19 13:22 ` [PATCH v2 19/47] Windows gdb: Pending stop and current_event Pedro Alves
2025-05-19 13:22 ` [PATCH v2 20/47] Windows gdb+gdbserver: Elim desired_stop_thread_id / rework pending_stops Pedro Alves
2025-05-30 20:41   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 21/47] Windows gdb+gdbserver: Introduce get_last_debug_event_ptid Pedro Alves
2025-05-28 19:21   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 22/47] Windows gdb: Can't pass signal to thread other than last stopped thread Pedro Alves
2025-05-28 19:22   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 23/47] Windows gdbserver: Fix scheduler-locking Pedro Alves
2025-05-30 20:37   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 24/47] Windows gdb: Enable "set scheduler-locking on" Pedro Alves
2025-05-19 13:22 ` [PATCH v2 25/47] Windows gdbserver: Eliminate soft-interrupt mechanism Pedro Alves
2025-05-19 13:22 ` [PATCH v2 26/47] Windows gdb+gdbserver: Make current_event per-thread state Pedro Alves
2025-05-28 19:30   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 27/47] Windows gdb+gdbserver: Make last_sig " Pedro Alves
2025-05-28 19:31   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 28/47] Windows gdb+gdbserver: Make siginfo_er " Pedro Alves
2025-05-28 19:33   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 29/47] Add backpointer from windows_thread_info to windows_process_info Pedro Alves
2025-05-19 13:22 ` [PATCH v2 30/47] Windows gdb+gdbserver: Share $_siginfo reading code Pedro Alves
2025-05-19 13:22 ` [PATCH v2 31/47] Windows gdb+gdbserver: Eliminate struct pending_stop Pedro Alves
2025-05-28 19:36   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 32/47] Windows gdb: Change serial_event management Pedro Alves
2025-05-28 19:37   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 33/47] Windows gdb: cygwin_set_dr => windows_set_dr, etc Pedro Alves
2025-05-19 13:22 ` [PATCH v2 34/47] Windows gdb: Avoid writing debug registers if watchpoint hit pending Pedro Alves
2025-05-30 20:43   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 35/47] Windows gdb+gdbserver: Check whether DBG_REPLY_LATER is available Pedro Alves
2025-05-19 13:22 ` [PATCH v2 36/47] linux-nat: Factor out get_detach_signal code to common code Pedro Alves
2025-05-28 19:44   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 37/47] Windows GDB: make windows_thread_info be private thread_info data Pedro Alves
2025-05-28 19:52   ` Tom Tromey
2025-05-19 13:22 ` [PATCH v2 38/47] Introduce windows_nat::event_code_to_string Pedro Alves
2025-05-28 19:53   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 39/47] Windows gdb: Add non-stop support Pedro Alves
2025-06-05 16:21   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 40/47] Windows gdb: Eliminate invalidate_context Pedro Alves
2025-05-28 19:54   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 41/47] Windows gdb: Watchpoints while running (internal vs external stops) Pedro Alves
2025-05-30 20:50   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 42/47] gdb_test_multiple: Anchor prompt match if -lbl Pedro Alves
2025-05-21 15:19   ` Tom de Vries
2025-05-27 22:41     ` Pedro Alves
2025-05-27 23:20       ` Pedro Alves
2025-05-28 11:59         ` [PATCH v2] of " Pedro Alves
2025-06-05 16:37           ` Pedro Alves
2025-06-05 17:20             ` [PATCH v3] " Pedro Alves
2025-06-06  9:58               ` Tom de Vries
2025-06-06 13:53                 ` Pedro Alves
2025-05-19 13:23 ` [PATCH v2 43/47] Windows gdb: extra thread info => show exiting Pedro Alves
2025-05-28 19:58   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 44/47] Add gdb.threads/leader-exit-schedlock.exp Pedro Alves
2025-05-29 16:09   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 45/47] infrun: with AS+NS, prefer process exit over thread exit Pedro Alves
2025-05-19 13:23 ` [PATCH v2 46/47] Windows gdb: Always non-stop (default to "maint set target-non-stop on") Pedro Alves
2025-05-29 16:02   ` Tom Tromey
2025-05-19 13:23 ` [PATCH v2 47/47] Mention Windows scheduler-locking and non-stop support in NEWS Pedro Alves
2025-05-19 14:07   ` Eli Zaretskii
2025-06-05 17:57 ` [PATCH v2 00/47] Windows non-stop mode Tom Tromey
2025-06-11 22:06   ` Pedro Alves [this message]
2026-04-02 12:21     ` [PATCH] Improve attach on Windows Pedro Alves
2026-04-02 18:52       ` Tom Tromey
2025-06-11 23:51   ` [PATCH v2 00/47] Windows non-stop mode Pedro Alves
2025-06-12 19:23     ` Tom Tromey
2025-06-13 10:34       ` Pedro Alves
2025-06-13 14:23         ` 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=becd6119-3b7a-414e-87d3-c449d2f4095d@palves.net \
    --to=pedro@palves.net \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@adacore.com \
    /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