Subject: standards/19837: signal(SIGCHLD, SIG_IGN) should prevent zombies
To: None <gnats-bugs@gnats.netbsd.org>
From: Stephen Ma <stephenm@employees.org>
List: netbsd-bugs
Date: 01/13/2003 02:51:17
>Number:         19837
>Category:       standards
>Synopsis:       signal(SIGCHLD, SIG_IGN) should prevent zombies
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    standards-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 13 06:45:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stephen Ma
>Release:        NetBSD 1.6L 2003-01-04
>Organization:
	People's Front for the correct spelling of the word "Organisation"
>Environment:
System: NetBSD whitewater.local 1.6L NetBSD 1.6L (WHITEWATER) #63: Mon Jan 13 02:09:27 PST 2003 stephenm@whitewater.local:/v1/netbsd/obj/src/sys/arch/i386/compile/WHITEWATER i386
Architecture: i386
Machine: i386
>Description:
According to IEEE 1003.1-2001, when the signal handler for SIGCHLD is set
to SIG_IGN, exiting child processes should not become zombies. NetBSD
currently only pays attention to the SA_NOCLDWAIT flag, not the signal
handler to decide whether or not to flag the prevention of zombies.
>How-To-Repeat:
The following code should not show the child process as a zombie.

#include <signal.h>
#include <unistd.h>

int
main(int argc, char **argv) 
{
	signal(SIGCHLD, SIG_IGN);
	
	if (fork()) {
		/* parent */
		usleep(10000);
		system("ps -uxT");
	} else {
		/* child */
		exit(0);
	}

	return 0;
}
  
>Fix:
I'm not sure if this is entirely correct - it simply treats the SIG_IGN
for SIGCHLD as equivalent to SA_NOCLDWAIT.

src/sys/kern/kern_sig.c:
     $NetBSD: kern_sig.c,v 1.129 2002/12/06 22:44:49 christos Exp $

--- /v1/netbsd/src/sys/kern/kern_sig.c	Sat Dec  7 03:04:56 2002
+++ ./kern_sig.c	Mon Jan 13 02:08:53 2003
@@ -210,7 +210,8 @@ sigaction1(struct proc *p, int signum, c
 				p->p_flag |= P_NOCLDSTOP;
 			else
 				p->p_flag &= ~P_NOCLDSTOP;
-			if (nsa->sa_flags & SA_NOCLDWAIT) {
+			if ((nsa->sa_flags & SA_NOCLDWAIT) ||
+			    (nsa->sa_handler == SIG_IGN)) {
 				/*
 				 * Paranoia: since SA_NOCLDWAIT is implemented
 				 * by reparenting the dying child to PID 1 (and

>Release-Note:
>Audit-Trail:
>Unformatted: