diff options
author | Pedro Alves <palves@redhat.com> | 2015-11-30 16:05:23 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-11-30 18:41:26 +0000 |
commit | a681f9c91372d282229f6d58ba235ef0dd3644fb (patch) | |
tree | 5d65ed73403994a16420c65c142308dcc84f8fea | |
parent | 65706a29bac50c2c971227a1945e46502845766b (diff) | |
download | gdb-a681f9c91372d282229f6d58ba235ef0dd3644fb.zip gdb-a681f9c91372d282229f6d58ba235ef0dd3644fb.tar.gz gdb-a681f9c91372d282229f6d58ba235ef0dd3644fb.tar.bz2 |
gdbserver: fix killed-outside.exp
killed-outside.exp regresses with "maint set target-non-stop on". The
logs show:
(gdb) continue
Continuing.
infrun: clear_proceed_status_thread (Thread 9028.9028)
infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
infrun: proceed: resuming Thread 9028.9028
Sending packet: $Z0,3615a03966,1#4b... Notification received: Stop:X9;process:2344
Packet received: E01
Sending packet: $Z0,3615a13970,1#47...Packet received: E01
Sending packet: $Z0,3615a14891,1#4a...Packet received: E01
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 9028.9028] at 0x4005e4
Sending packet: $vCont;c:p2344.2344#1a...Packet received: E.target not running.
Sending packet: $qXfer:threads:read::0,fff#03...Packet received: l<threads>\n</threads>\n
Sending packet: $vStopped#55...Packet received: OK
Unexpected vCont reply in non-stop mode: E.target not running.
(gdb) remote_async_inferior_event_handler
infrun: target_wait (-1.0.0, status) =
infrun: 9028.0.0 [process 9028],
infrun: status->kind = signalled, signal = GDB_SIGNAL_KILL
infrun: TARGET_WAITKIND_SIGNALLED
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
infrun: stop_waiting
infrun: clear_step_over_info
infrun: stop_all_threads
remote_thread_exit_events(1)
Note the "Unexpected vCont reply" error.
I traced it to a problem in status_pending_p_callback. It resumes an
LWP when it shouldn't.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (thread_still_has_status_pending_p): Don't check
vCont;t here.
(lwp_resumed): New function.
(status_pending_p_callback): Return early if the LWP is not
supposed to be resumed.
-rw-r--r-- | gdb/gdbserver/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 29 |
2 files changed, 31 insertions, 6 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 2d04899..bc09844 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,13 @@ 2015-11-30 Pedro Alves <palves@redhat.com> + * linux-low.c (thread_still_has_status_pending_p): Don't check + vCont;t here. + (lwp_resumed): New function. + (status_pending_p_callback): Return early if the LWP is not + supposed to be resumed. + +2015-11-30 Pedro Alves <palves@redhat.com> + * linux-low.c (handle_extended_wait): Assert that the LWP's waitstatus is TARGET_WAITKIND_IGNORE. If GDB wants to hear about thread create events, leave the new child's status pending. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index cde59a7..07cb831 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -1525,12 +1525,6 @@ thread_still_has_status_pending_p (struct thread_info *thread) if (!lp->status_pending_p) return 0; - /* If we got a `vCont;t', but we haven't reported a stop yet, do - report any status pending the LWP may have. */ - if (thread->last_resume_kind == resume_stop - && thread->last_status.kind != TARGET_WAITKIND_IGNORE) - return 0; - if (thread->last_resume_kind != resume_stop && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)) @@ -1587,6 +1581,26 @@ thread_still_has_status_pending_p (struct thread_info *thread) return 1; } +/* Returns true if LWP is resumed from the client's perspective. */ + +static int +lwp_resumed (struct lwp_info *lwp) +{ + struct thread_info *thread = get_lwp_thread (lwp); + + if (thread->last_resume_kind != resume_stop) + return 1; + + /* Did gdb send us a `vCont;t', but we haven't reported the + corresponding stop to gdb yet? If so, the thread is still + resumed/running from gdb's perspective. */ + if (thread->last_resume_kind == resume_stop + && thread->last_status.kind == TARGET_WAITKIND_IGNORE) + return 1; + + return 0; +} + /* Return 1 if this lwp has an interesting status pending. */ static int status_pending_p_callback (struct inferior_list_entry *entry, void *arg) @@ -1600,6 +1614,9 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg) if (!ptid_match (ptid_of (thread), ptid)) return 0; + if (!lwp_resumed (lp)) + return 0; + if (lp->status_pending_p && !thread_still_has_status_pending_p (thread)) { |