Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore SIGCHLD to prevent creating zombies #279

Merged
merged 1 commit into from
Oct 16, 2022

Conversation

oxalica
Copy link
Contributor

@oxalica oxalica commented Oct 4, 2022

As #200 (comment) pointed out, calling waitpid once on SIGCHLD is not enough. Multiple children may died during the delivery of the signal. I also hit this in production with earlyoom 1.7.

This PR uses signal(SIGCHLD, SIG_IGN); to prevents creations of zombies.
In manual sigaction(2),

POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN.
POSIX.1-2001 and later allow this possibility, so that ignoring SIGCHLD
can be used to prevent the creation of zombies (see wait(2)).

I think relying on POSIX 2001 should be enough for us. But note that ignoring SIGCHLD seems also prevent any usage of wait* functions. Currently we doesn't do it. Alternatively, we could run a loop in the signal handler to achieve the same goal.

Here is the test which proves a single waitpid is not enough,

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <spawn.h>

void handler(int _sig) {
    waitpid(-1, NULL, WNOHANG);
}

int main() {
    /* This still makes some zombies. The actual number of zombies may varies. */
    signal(SIGCHLD, handler);
    /* This creates no zombies always. */
    /* signal(SIGCHLD, SIG_IGN); */

    char *args[] = { "true", NULL };
    for (int i = 0; i < 128; ++i)
        posix_spawnp(NULL, args[0], NULL, NULL, args, NULL);

    puts("spawned");
    for(;;)
        sleep(1);
}

Calling `waitpid` once in SIGCHLD is not enough. Multiple children may
died during the delivery of the signal.

In sigaction(2),
> POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN.
> POSIX.1-2001 and later allow this possibility, so that ignoring SIGCHLD
> can be used to prevent the creation of zombies (see wait(2)).
@rfjakob rfjakob merged commit 1975ed7 into rfjakob:master Oct 16, 2022
@rfjakob
Copy link
Owner

rfjakob commented Oct 16, 2022

❤️

@oxalica oxalica deleted the fix/zombie branch October 16, 2022 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants