2003-05-22 Roland McGrath <roland@redhat.com>

* defs.h (struct tcb): New member `nzombies'.
	* strace.c (alloctcb): Initialize it.
	(droptcb): Increment our parent's zombie count.
	* process.c (internal_wait): Don't go into TCB_SUSPENDED if the
	process has zombies it can reap.  On the way out, if we reaped
	an untraced process, decrement the zombie count.
This commit is contained in:
Roland McGrath 2003-05-23 02:27:13 +00:00
parent 7dfd4ed721
commit 0962345a57
3 changed files with 25 additions and 1 deletions

1
defs.h
View File

@ -263,6 +263,7 @@ struct tcb {
struct tcb *parent; /* Parent of this process */
int nchildren; /* # of traced children */
int waitpid; /* pid(s) this process is waiting for */
int nzombies; /* # of formerly traced children now dead */
#ifdef LINUX
int nclone_threads; /* # of nchildren with CLONE_THREAD */
int nclone_detached; /* # of nchildren with CLONE_DETACHED */

View File

@ -1774,7 +1774,17 @@ struct tcb *tcp;
/* ??? WTA: fix bug with hanging children */
if (!(tcp->u_arg[2] & WNOHANG)) {
/* There are traced children */
/*
* There are traced children. We'll make the parent
* block to avoid a false ECHILD error due to our
* ptrace having stolen the children. However,
* we shouldn't block if there are zombies to reap.
* XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
*/
if (tcp->nzombies > 0 &&
(tcp->u_arg[0] == -1 ||
pid2tcb(tcp->u_arg[0]) == NULL))
return 0;
tcp->flags |= TCB_SUSPENDED;
tcp->waitpid = tcp->u_arg[0];
#ifdef TCB_CLONE_THREAD
@ -1795,6 +1805,14 @@ struct tcb *tcp;
"internal_wait: should not have resumed %d\n",
tcp->pid);
}
else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
/*
* We just reaped a child we don't know about,
* presumably a zombie we already droptcb'd.
*/
tcp->nzombies--;
}
return 0;
}

View File

@ -621,6 +621,7 @@ int pid;
tcp->pid = pid;
tcp->parent = NULL;
tcp->nchildren = 0;
tcp->nzombies = 0;
#ifdef TCB_CLONE_THREAD
tcp->nclone_threads = tcp->nclone_detached = 0;
tcp->nclone_waiting = 0;
@ -1011,6 +1012,10 @@ struct tcb *tcp;
if (tcp->flags & TCB_CLONE_THREAD)
tcp->parent->nclone_threads--;
#endif
#ifdef TCB_CLONE_DETACHED
if (!(tcp->flags & TCB_CLONE_DETACHED))
#endif
tcp->parent->nzombies++;
tcp->parent = NULL;
}