[PATCH] fix bogus ECHILD return from wait* with zombie group leader
From: Roland McGrath
Date: Sat Dec 04 2004 - 17:22:44 EST
Klaus Dittrich observed this bug and posted a test case for it. This patch
fixes both that failure mode and some others possible. What Klaus saw was
a false negative (i.e. ECHILD when there was a child) when the group leader
was a zombie but delayed because other children live; in the test program
this happens in a race between the two threads dying on a signal. The
change to the TASK_TRACED case avoids a potential false positive (blocking,
or WNOHANG returning 0, when there are really no children left), in the
race condition where my_ptrace_child returns zero.
Thanks,
Roland
Signed-off-by: Roland McGrath <roland@xxxxxxxxxx>
--- linux-2.6/kernel/exit.c
+++ linux-2.6/kernel/exit.c
@@ -1319,6 +1319,10 @@ static long do_wait(pid_t pid, int optio
add_wait_queue(¤t->wait_chldexit,&wait);
repeat:
+ /*
+ * We will set this flag if we see any child that might later
+ * match our criteria, even if we are not able to reap it yet.
+ */
flag = 0;
current->state = TASK_INTERRUPTIBLE;
read_lock(&tasklist_lock);
@@ -1337,11 +1341,14 @@ repeat:
switch (p->state) {
case TASK_TRACED:
- flag = 1;
if (!my_ptrace_child(p))
continue;
/*FALLTHROUGH*/
case TASK_STOPPED:
+ /*
+ * It's stopped now, so it might later
+ * continue, exit, or stop again.
+ */
flag = 1;
if (!(options & WUNTRACED) &&
!my_ptrace_child(p))
@@ -1377,8 +1384,12 @@ repeat:
goto end;
break;
}
- flag = 1;
check_continued:
+ /*
+ * It's running now, so it might later
+ * exit, stop, or stop and then continue.
+ */
+ flag = 1;
if (!unlikely(options & WCONTINUED))
continue;
retval = wait_task_continued(
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/