NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/57527: system() waits for last child if SIG_CHLD is ignored



>Number:         57527
>Category:       kern
>Synopsis:       system() waits for last child if SIG_CHLD is ignored
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 15 15:20:00 +0000 2023
>Originator:     Michael van Elst
>Release:        NetBSD 10.99.5
>Organization:
-- 
                                Michael van Elst
Internet: mlelstv%serpens.de@localhost
                                "A potential Snark may lurk in every tree."
>Environment:
System: NetBSD tazz 10.99.5 NetBSD 10.99.5 (TAZZ) #268: Sat Jul 15 14:39:30 UTC 2023 mlelstv@slowpoke:/scratch2/obj.amd64/scratch/netbsd-current/src/sys/arch/amd64/compile/TAZZ amd64
Architecture: x86_64
Machine: amd64
>Description:

When you ignore SIGCHLD to avoid zombies, then a call to system()
waits until the last child exited.

This is actually wait() or waitpid() waiting (which are called by system()).

>How-To-Repeat:

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

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

	pid_t pid;

	pid = fork();
	if (pid == 0) {
		sleep(4);
		_exit(0);
	}

	signal(SIGCHLD, SIG_IGN);

	system("sleep 1");

	return 0;
}

Sleeps 4 seconds on NetBSD and 1 second on Linux.

Tis behaviour comes explicit from exit1() in kern_exit.c:

                /*
                 * If this was the last child of our parent, notify
                 * parent, so in case he was wait(2)ing, he will
                 * continue.
                 */
                if (LIST_FIRST(&old_parent->p_children) == NULL)
                        cv_broadcast(&old_parent->p_waitcv);

FreeBSD doesn't have such a condition and always wakes the parent.

                         /*
                          * Notify parent, so in case he was wait(2)ing or
                          * executing waitpid(2) with our pid, he will
                          * continue.
                          */
                         wakeup(pp);

Removing the condition in exit1() fixes the behaviour, but there might
be side effects.

>Fix:
	



Home | Main Index | Thread Index | Old Index