Hi,
> > void
> > sigchld(int unused)
> > {
> > + if (signal(SIGCHLD, sigchld) == SIG_ERR)
> > + die("can't install SIGCHLD handler:");
> > while (0 < waitpid(-1, NULL, WNOHANG));
> > }
>
> Calling `die` inside a signhandler is still an issue and can produce
> bad behavior (I have seen a couple software which randomly freeze due to
> calling signal unsafe functions inside a sighandler).
>
> If `sigaction` can fix the issue with `signal` then it's probably best
> to use that. Otherwise replacing `die` with `write` and `_exit` is also
> a viable solution as shown in: https://lists.suckless.org/hackers/2207/18405.html
Indeed. in both things, we should not use die() in a signal handler and using
signal to reinstall the handler opens a race condition window where we can lose
sigchld signals and generate zombies process.
I personally think that using a sigchld handler to collect zomby process
is a bad idea. I think it is POSIX that if you use an explicit signal call to
ignore SIGCHLD then the system reap them automatically without explicits
wait [1]. I could not find this specification in the POSIX standard, but [2]
says:
POSIX.1-2001 specifies that if the disposition of SIGCHLD
is set to SIG_IGN or the SA_NOCLDWAIT flag is set for SIGCHLD
(see sigaction(2)), then children that terminate do not
become zombies and a call to wait() or waitpid() will block
until all children have terminated, and then fail with errno
set to ECHILD.
So it seems it is standard since long time ago.
[1]
https://copyprogramming.com/howto/what-is-the-use-of-ignoring-sigchld-signal-with-sigaction-2
[2]
https://corp.sonic.net/ceo/perl-sigchld-ignore-system-and-you/
Roberto Vargas,
Received on Wed Jul 27 2022 - 07:52:50 CEST