[PATCH 2/3] Initialize last_resume_kind for remote fork child

Don Breazeal
2015-05-22T18:55:57Z

This patch fixes some intermittent test failures in
gdb.base/foll-vfork.exp where a vfork child could sometimes be
(incorrectly) resumed when handling the vfork event. In this
case the result was a subsequent event reported to the client
side as a SIGTRAP delivered to the as-yet-unknown child thread.

The fix is to initialize the threadinfo.last_resume_kind field
for new fork children in gdbserver/linux-low.c:handle_extended_wait.
This prevents the event handler from incorrectly resuming the child
if the stop event that is generated when it starts is reported
before the vfork event that initiated it. The same thing is done
for the native case in linux-nat.c:linux_child_follow_fork.

In addition, it seemed prudent to initialize lwp_info.status_pending_p
for the new fork child. I also rearranged the initialization code
so that all of the lwp_info initialization was together, rather than
intermixed with thread_info and process_info initialization.

Tested native, native-gdbserver, native-extended-gdbserver on
x86_64 GNU/Linux.

OK?

Thanks
--Don

gdb/gdbserver/
2015-05-22 Don Breazeal <donb@codesourcery.com>

* linux-low.c (handle_extended_wait):

---
gdb/gdbserver/linux-low.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 9f3ea48..d763c66 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -457,6 +457,7 @@ handle_extended_wait (struct lwp_info *event_lwp, int wstat)
struct process_info *parent_proc;
struct process_info *child_proc;
struct lwp_info *child_lwp;
+ struct thread_info *child_thr;
struct target_desc *tdesc;

ptid = ptid_build (new_pid, new_pid, 0);
@@ -479,6 +480,10 @@ handle_extended_wait (struct lwp_info *event_lwp, int wstat)
child_lwp = add_lwp (ptid);
gdb_assert (child_lwp != NULL);
child_lwp->stopped = 1;
+ child_lwp->must_set_ptrace_flags = 1;
+ child_lwp->status_pending_p = 0;
+ child_thr = get_lwp_thread (child_lwp);
+ child_thr->last_resume_kind = resume_stop;
parent_proc = get_thread_process (event_thr);
child_proc->attached = parent_proc->attached;
clone_all_breakpoints (&child_proc->breakpoints,
@@ -488,7 +493,6 @@ handle_extended_wait (struct lwp_info *event_lwp, int wstat)
tdesc = xmalloc (sizeof (struct target_desc));
copy_target_description (tdesc, parent_proc->tdesc);
child_proc->tdesc = tdesc;
- child_lwp->must_set_ptrace_flags = 1;

/* Clone arch-specific process data. */
if (the_low_target.new_fork != NULL)
--
1.8.1.1