If a process is started with RFNOWAIT, up->parent points to the parent's Proc but up->parentpid is set to 0 (not the parent's actual pid). If the parent exits before the child, its pid becomes 0, and when the child exits later, this code p = up->parent; .... /* * Check that parent is still alive. */ if(p->pid == up->parentpid && p->state != Broken) { incorrectly treats the parent as still alive (because up->parent->pid and up->parentpid are both zero). So the exiting child's wait record is passed to the dead parent ... or worse, if another fork occurs soon which reuses the parent's Proc, we have a race which can pass the child's wait record to some random new process (and decrement its p->nchild field). This results in a "no living children" error if the new process tries to wait for its real children. The correction is to avoid the above check when up->parentpid == 0. Reference: /n/sources/patch/exit-wrong-parent Date: Thu Apr 5 21:37:43 GMT 2018 Signed-off-by: miller@hamnavoe.com --- /sys/src/9/port/proc.c Thu Apr 5 13:39:47 2018 +++ /sys/src/9/port/proc.c Thu Apr 5 13:39:42 2018 @@ -1153,7 +1153,7 @@ pexit(char *exitstr, int freemem) * if not a kernel process and have a parent, * do some housekeeping. */ - if(up->kp == 0) { + if(up->kp == 0 && up->parentpid != 0) { p = up->parent; if(p == 0) { if(exitstr == 0)