This is the mail archive of the mailing list for the GDB project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] gdbserver: keep event_child and current_inferior in sync


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->;

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  <>

	* 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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]