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. Note: this patch incorporates the changes from earlier patch proc-smp-fixes, and therefore supersedes it. It may be necessary to revert proc-smp-fixes before applying this patch. Reference: /n/sources/patch/exit-wrong-parent Date: Thu Apr 5 23:37:43 CES 2018 Signed-off-by: miller@hamnavoe.com --- /sys/src/9/port/proc.c Thu Apr 5 15:39:47 2018 +++ /sys/src/9/port/proc.c Thu Apr 5 15:39:42 2018 @@ -471,8 +471,6 @@ p = rq->head; if(p == nil) continue; - if(p->mp != MACHP(m->machno)) - continue; if(pri == p->basepri) continue; updatecpu(p); @@ -1108,7 +1106,7 @@ * 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) @@ -1299,7 +1297,7 @@ /* * wait till all processes have flushed their mmu - * state about segement s + * state about segment s */ void procflushseg(Segment *s) @@ -1336,10 +1334,13 @@ * wait for all processors to take a clock interrupt * and flush their mmu's */ - for(nm = 0; nm < conf.nmach; nm++) - if(MACHP(nm) != m) - while(MACHP(nm)->flushmmu) - sched(); +again: + for(nm = 0; nm < conf.nmach; nm++){ + if(nm != m->machno && MACHP(nm)->flushmmu){ + sched(); + goto again; + } + } } void