[PATCH] gdbserver: keep event_child and current_inferior in sync
Doug Evans
dje@google.com
Mon Jan 27 20:01:00 GMT 2014
Hi.
I ran into this while debugging some testsuite failures in my rewrite
of speeding up gdbserver attach.
linux_wait_1 calls linux_wait_for_event, and one of the things
linux_wait_for_event does is set current_inferior (blech, but
a cleanup for another day).
linux_wait_1 then sets event_child to the "lwp" part of current_inferior here:
event_child = get_thread_lwp (current_inferior);
and assumes the two remain in sync.
However later it calls select_event_lwp to pick an event to report back:
select_event_lwp (&event_child);
but doesn't update current_inferior. Later code then does:
if (current_inferior->last_resume_kind == resume_stop
&& WSTOPSIG (w) == SIGSTOP)
which can use a stale current_inferior.
In my patch to speed up attach I see the bug more easily because
I changed the end of the function to be (effectively):
- return ptid_of (event_child);
+ return current_inferior->entry.id;
FAIL: gdb.threads/watchthreads.exp: threaded watch loop
FAIL: gdb.threads/watchthreads.exp: combination of threaded watchpoints = 30
The test fails because a h/w watchpoint is missed, and that happens
because linux_wait_1 reports the wrong thread.
2014-01-27 Doug Evans <dje@google.com>
* linux-low.c (linux_wait_for_event): Improve comment.
(linux_wait_1): Keep current_inferior in sync with event_child.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index bac6134..c72d681 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -1756,7 +1756,7 @@ ptid_t step_over_bkpt;
child. Store the stop status through the status pointer WSTAT.
OPTIONS is passed to the waitpid call. Return 0 if no child stop
event was found and OPTIONS contains WNOHANG. Return the PID of
- the stopped child otherwise. */
+ the stopped child and update current_inferior otherwise. */
static int
linux_wait_for_event (ptid_t ptid, int *wstat, int options)
@@ -2681,6 +2681,9 @@ retry:
select_event_lwp (&event_child);
+ /* current_inferior and event_child must stay in sync. */
+ current_inferior = get_lwp_thread (event_child);
+
event_child->status_pending_p = 0;
w = event_child->status_pending;
}
More information about the Gdb-patches
mailing list