This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Fix foll-fork.exp foll-vfork.exp fork-child-threads.exp
- From: Michael Snyder <msnyder at vmware dot com>
- To: Pedro Alves <pedro at codesourcery dot com>
- Cc: "gdb-patches at sourceware dot org" <gdb-patches at sourceware dot org>
- Date: Mon, 01 Dec 2008 10:58:31 -0800
- Subject: Re: Fix foll-fork.exp foll-vfork.exp fork-child-threads.exp
- References: <200811201328.13651.pedro@codesourcery.com>
Pedro Alves wrote:
Long story short:
After following a child, detaching from the parent,
('set follow-fork-mode child' + 'set detach-on-fork on')
here in this bit,
infrun.c:resume():
{
....
follow_fork ();
...
tp->stop_signal = TARGET_SIGNAL_0;
}
... `tp' is no longer in the thread list (it was pointing at a thread
of the parent process, which we've detached from, hence no longer
in the thread list), so if the assignment above doesn't crash, it ends
up writing to who-knows-where.
With some local changes I was making, sometimes, `tp' happened to be left pointing
at linux_nat.c:lwp_list, and so that assignment above ended up clearing
lp->waitstatus.kind (of the first lwp in the list), which resulted in
GDB considering that the child process had
exited (because TARGET_SIGNAL_0 == TARGET_WAITKIND_EXITED).
This should fix intermittent foll-fork.exp foll-vfork.exp
fork-child-threads.exp failures.
Checked in.
Pedro,
I'm not sure if this change goes far enough.
If a multi-threaded program forks, only the currently
executing thread survives in the child. All others are
left behind (and its not unlikely that the thread library
is left in an inconsistant state, possibly leading to
deadlocks).
We can't do anything about that, but we could, eg.,
invalidate all known debugger state having to do with
other threads. Clear the gdb thread list and preserve
only the current thread.
What do you think?
------------------------------------------------------------------------
2008-11-20 Pedro Alves <pedro@codesourcery.com>
* infrun.c (resume): If following a fork, reread the current
thread. Avoid dereferencing a possibly dangling pointer.
---
gdb/infrun.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c 2008-11-20 05:37:35.000000000 +0000
+++ src/gdb/infrun.c 2008-11-20 12:30:26.000000000 +0000
@@ -1053,6 +1053,9 @@ a command like `return' or `jump' to con
pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
if (follow_fork ())
should_resume = 0;
+
+ /* Following a fork may change inferior_ptid. */
+ tp = inferior_thread ();
break;
case TARGET_WAITKIND_EXECD:
@@ -1148,11 +1151,11 @@ a command like `return' or `jump' to con
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
}
- target_resume (resume_ptid, step, sig);
-
/* Avoid confusing the next resume, if the next stop/resume
happens to apply to another thread. */
tp->stop_signal = TARGET_SIGNAL_0;
+
+ target_resume (resume_ptid, step, sig);
}
discard_cleanups (old_cleanups);