This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
PTRACE_EVENT_CLONE patch causing deadlock?
- From: Ulrich Weigand <weigand at i1 dot informatik dot uni-erlangen dot de>
- To: gdb at sources dot redhat dot com, drow at false dot org
- Date: Wed, 28 Jul 2004 22:00:23 +0200 (CEST)
- Subject: PTRACE_EVENT_CLONE patch causing deadlock?
Hello,
we're seeing deadlocks when running clone testcases under gdb;
these appear to have been introduced by this patch:
http://sources.redhat.com/ml/gdb-patches/2004-03/msg00672.html
(Reverting the patch removes the deadlock, in any case.)
What happens is that gdb runs an inferior process A, which
does a clone to create B. We get a PTRACE_EVENT_CLONE
reported for A, with 'related_pid' specifying B.
Now, this piece of code in child_wait:
/* Handle GNU/Linux's extended waitstatus for trace events. */
if (pid != -1 && WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP
&& status >> 16 != 0)
{
linux_handle_extended_wait (pid, status, ourstatus);
/* If we see a clone event, detach the child, and don't
report the event. It would be nice to offer some way to
switch into a non-thread-db based threaded mode at this
point. */
if (ourstatus->kind == TARGET_WAITKIND_SPURIOUS)
{
ptrace (PTRACE_DETACH, ourstatus->value.related_pid, 0, 0);
ourstatus->kind = TARGET_WAITKIND_IGNORE;
pid = -1;
save_errno = EINTR;
}
}
handles that event and detached from B. However, it then goes
right on to repeat the main loop, and issue another waitpid on A.
However, A is still stopped because of the PTRACE_EVENT_CLONE
delivery, and noone has actually issued a PTRACE_CONT to let it
go running again. Thus the waitpid never stops ...
How's this supposed to work? What am I missing?
The test case I'm using is the following, running under a
current pre-2.6.8 kernel and gdb CVS head.
#include <sched.h>
int
child_environ(void * dummy)
{
exit(0);
}
int
main(int ac, char **av)
{
void *child_stack;
child_stack = (void *) malloc(16384);
clone(&child_environ, child_stack + 16384, 0, 0);
free(child_stack);
return 0;
}
(This has other problems, sure, but it shouldn't deadlock
in the way I've described ...)
Bye,
Ulrich
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de