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