Search code examples
csignalsfork

Fork child process terminates with signal 0


I have a small function that should give me information about how a child process finished.

int debug_wait() {
    int status;
    wait(&status);
    if (WIFSIGNALED(status)) {
        int sig = WSTOPSIG(status);
        printf("failed with signal %d (%s)\n", sig, strsignal(sig));
        return 1;
    }
    else if (!WIFEXITED(status)) {
        printf("ended in an unexpected way\n");
        return 1;
    }
    return 0;
}

But I get the following result:

double free or corruption (out)
tests failed with signal 0 (Unknown signal 0)

I know I should fix my code, but why do I get signal no. 0? Is there a mistake in my function or does it have an other meaning?

Since people asked, here is a example program:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>

int debug_wait() {
    int status;
    wait(&status);
    if (WIFSIGNALED(status)) {
        int sig = WSTOPSIG(status);
        printf("tests failed with signal %d (%s)\n", sig, strsignal(sig));
        return 1;
    }
    else if (!WIFEXITED(status)) {
        printf("tests ended in an unexpected way\n");
        return 1;
    }
    return 0;
}

int main() {
    void* ptr = malloc(10);
    pid_t pid = fork();
    if (pid == 0) {
        free(ptr);
        free(ptr);
    }
    else {
        debug_wait();
    }
}

Solution

  • You are decoding the wrong thing. If WIFSIGNALED is true you can use WTERMSIG and WCOREDUMP (check #ifdef WCOREDUMP first). To decude the WSTOPSIG then WIFSTOPPED must be true.

    Example:

    int status;
    pid_t pid = wait(&status);
    if (pid == -1) return 1;
    
    if (WIFEXITED(status)) {
        printf("normal exit %d\n", WEXITSTATUS(status));
    
    } else if (WIFSIGNALED(status)) {
        printf("termsig %d core dump=%c\n", WTERMSIG(status),
                WCOREDUMP(status) ? 'Y' : 'N');
    
    } else if (WIFSTOPPED(status)) {
        printf("stop %d cont=%c\n", WSTOPSIG(status),
               WIFCONTINUED(status) ? 'Y' : 'N');
    }
    

    Without using the feature test macros:

    if (WIFEXITED(status)) {
        printf("normal exit %d\n", WEXITSTATUS(status));
    
    } else if (WIFSIGNALED(status)) {
        printf("termsig %d\n", WTERMSIG(status));
    
    } else if (WIFSTOPPED(status)) {
        printf("stop %d\n", WSTOPSIG(status));
    }