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 the 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
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 ();
}
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";
input. */
extern void reinstall_readline_callback_handler_cleanup ();
+/* 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 */
# 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"
}
}
- 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.
#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 ();
}