Hi,

Consider the following program that forks a child and then kills the entire 
process group

--8<---------------cut here---------------start------------->8---
#include <stdio.h>
#include <unistd.h>

#include <signal.h>

int
main(int argc, char** argv)
{

  pid_t pid;
  pid = fork();
  if (pid == 0)
    printf("Child %d \n", getpid());
  else {
    printf("Parent %d \n", getpid());
    printf("Killing all\n");
    sleep(5);
    kill(- getpid(), SIGTERM);
  }
  
  printf("Going to sleep zzzz  \n");
  sleep(3600);
  return 0;
}

--8<---------------cut here---------------end--------------->8---

Afterwards the child process is dead but never reaped as can be seen by "kill 
-0 PID" not failing with ESRCH.

In proc/mgt.c (process_has_exited) there is some logic to send SIGCHLD to the 
new parent but it does not do this check for the last child.

In case there is only one child this is completely ignored.
The attached patch should solve it.

Y.
>From 382c796742dad624d958ac283a7fb10960c742b1 Mon Sep 17 00:00:00 2001
From: Yelninei <[email protected]>
Date: Sat, 13 Dec 2025 17:55:08 +0000
Subject: [PATCH] proc: Also check whether the last child is already dead.

* proc/mgt.c (process_has_exited): Repeat check for the last child too.
---
 proc/mgt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/proc/mgt.c b/proc/mgt.c
index 3f04e2ba..dcb619af 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -1102,6 +1102,8 @@ process_has_exited (struct proc *p)
 				1, tp->p_pgrp->pg_pgid,
 				!tp->p_pgrp->pg_orphcnt);
       tp->p_parent = reparent_to;
+      if (tp->p_dead)
+	isdead = 1;
 
       /* And now append the lists. */
       tp->p_sib = reparent_to->p_ochild;
-- 
2.52.0

Reply via email to