This is the mail archive of the gdb@sources.redhat.com 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]

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


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