diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 9bc9fa37c4..82fb7f9bb2 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -483,6 +483,8 @@ handle_extended_wait (struct lwp_info *event_lwp, int wstat) child_lwp->status_pending_p = 0; child_thr = get_lwp_thread (child_lwp); child_thr->last_resume_kind = resume_stop; + child_thr->last_status.kind = TARGET_WAITKIND_STOPPED; + parent_proc = get_thread_process (event_thr); child_proc->attached = parent_proc->attached; clone_all_breakpoints (&child_proc->breakpoints, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index e3126edab1..eda6625c38 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-30 Pedro Alves + + * linux-low.c (handle_extended_wait): Set the child's last + reported status to TARGET_WAITKIND_STOPPED. + 2015-07-30 Pedro Alves PR threads/18600 diff --git a/gdb/testsuite/gdb.threads/fork-plus-threads.exp b/gdb/testsuite/gdb.threads/fork-plus-threads.exp index 8a503ec6c8..2b34b6c388 100644 --- a/gdb/testsuite/gdb.threads/fork-plus-threads.exp +++ b/gdb/testsuite/gdb.threads/fork-plus-threads.exp @@ -51,13 +51,45 @@ proc do_test { detach_on_fork } { } } + # gdbserver had a bug that resulted in reporting the fork child's + # initial stop to gdb, which gdb does not expect, in turn + # resulting in a broken session, like: + # + # [Thread 31536.31536] #16 stopped. <== BAD + # [New Thread 31547.31547] + # [Inferior 10 (process 31536) exited normally] + # [New Thread 31547.31560] + # + # [Thread 31547.31547] #18 stopped. <== BAD + # Cannot remove breakpoints because program is no longer writable. <== BAD + # Further execution is probably impossible. <== BAD + # [Inferior 11 (process 31547) exited normally] + # [Inferior 1 (process 31454) exited normally] + # + # These variables track whether we see such broken behavior. + set saw_cannot_remove_breakpoints 0 + set saw_thread_stopped 0 + set test "inferior 1 exited" gdb_test_multiple "" $test { + -re "Cannot remove breakpoints" { + set saw_cannot_remove_breakpoints 1 + exp_continue + } + -re "Thread \[^\r\n\]+ stopped\\." { + set saw_thread_stopped 1 + exp_continue + } -re "Inferior 1 \(\[^\r\n\]+\) exited normally" { pass $test } } + gdb_assert !$saw_cannot_remove_breakpoints \ + "no failure to remove breakpoints" + gdb_assert !$saw_thread_stopped \ + "no spurious thread stop" + gdb_test "info threads" "No threads\." \ "no threads left"