linuxcrash-dumpssigaction

Both registering signal handler for SIGSEGV and still being able to create full crash dump from OS


We are using the standard pattern of registering custom signal handler for SIGSEGV with sigaction and then when segmentation fault occurs using the backtrace function to walk the stack and print it to some file. It is nice feature to have the backtrace in logs but it disables the OS writing the full dump of the crashed program which is more than useful. How is it possible to both catch the SIGSEGV, do custom handling, and also cause the OS to create the full dump as it would be in case of default action?

Can I for example call remember the oldact pointer to default handler (as described in man), and then call it directly from out custom handler? Needless to say we need crash to indicate the exact place where it happened. So for example re-registering handler to old value and implicitly crashing the program in other place would not work.


Solution

  • You can reset the sigaction after having handled the signal. Then the faulting instruction will re-run after returning from the handler, and fault again, leading to core dump.

    Here's an example:

    #include <signal.h>
    #include <unistd.h>
    
    struct sigaction oldSA;
    void handler(int signal)
    {
        const char msg[] = "Caught, should dump core now\n";
        write(STDERR_FILENO, msg, sizeof msg - 1);
    
        sigaction(SIGSEGV, &oldSA, NULL);
    }
    
    int main()
    {
        struct sigaction sa={0};
        sa.sa_handler=handler;
        sigaction(SIGSEGV, &sa, &oldSA);
    
        int* volatile p=NULL;
        *p=5; // cause segfault
    }
    

    Example run:

    $ gcc test.c -o test && ./test
    Caught, should dump core now
    Segmentation fault (core dumped)