diff options
-rw-r--r-- | gdb/linux-nat.c | 15 | ||||
-rw-r--r-- | gdb/testsuite/gdb.threads/step-over-exec.exp | 6 |
2 files changed, 21 insertions, 0 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 9b78fd1..5ee3227 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1986,6 +1986,21 @@ linux_handle_extended_wait (struct lwp_info *lp, int status) thread execs, it changes its tid to the tgid, and the old tgid thread might have not been resumed. */ lp->resumed = 1; + + /* All other LWPs are gone now. We'll have received a thread + exit notification for all threads other the execing one. + That one, if it wasn't the leader, just silently changes its + tid to the tgid, and the previous leader vanishes. Since + Linux 3.0, the former thread ID can be retrieved with + PTRACE_GETEVENTMSG, but since we support older kernels, don't + bother with it, and just walk the LWP list. Even with + PTRACE_GETEVENTMSG, we'd still need to lookup the + corresponding LWP object, and it would be an extra ptrace + syscall, so this way may even be more efficient. */ + for (lwp_info *other_lp : all_lwps_safe ()) + if (other_lp != lp && other_lp->ptid.pid () == lp->ptid.pid ()) + exit_lwp (other_lp); + return 0; } diff --git a/gdb/testsuite/gdb.threads/step-over-exec.exp b/gdb/testsuite/gdb.threads/step-over-exec.exp index 783f865..a8b01f8 100644 --- a/gdb/testsuite/gdb.threads/step-over-exec.exp +++ b/gdb/testsuite/gdb.threads/step-over-exec.exp @@ -102,6 +102,12 @@ proc do_test { execr_thread different_text_segments displaced_stepping } { gdb_breakpoint foo gdb_test "continue" "Breakpoint $decimal, foo .*" \ "continue to foo" + + # Test that GDB is able to kill the inferior. This may fail if + # e.g., GDB does not dispose of the pre-exec threads properly. + gdb_test "with confirm off -- kill" \ + "\\\[Inferior 1 (.*) killed\\\]" \ + "kill inferior" } foreach_with_prefix displaced_stepping {auto off} { |