Search code examples
clinux-kernelsegmentation-faultsignal-handling

When will Linux kernel reset the signal handler for SIGSEGV to SIG_DFL?


If I have set a signal handler for SIGSEGV, whereas a segmentation fault is generated like:

int *a = NULL;
*a = 1;

The handler will be invoked, but this signal handler will be invoked only once. So, I guess Linux kernel will reset the signal handler to SIG_DFL, but when? I want to know the details, so I checked the Linux kernel source code, but couldn't find the clue yet. Please show me the code if you know the details.


Solution

  • It depends on how you register the signal handler. With sigaction and without the SA_RESETHAND flag, there will be no resetting to SIG_DFL (although returning from a signal handler run in response to a SIGSEGV delivered due to a segmentation fault is technically UB). With SA_RESETHAND it will get reset, and if you register the handler with signal, then whether the handler will be reset or not is unspecified (so don't use signal()).

    Example:

    #include <signal.h>
    #include <unistd.h>
    
    int volatile*a;
    void h(int Sig) { write(1,"h\n", 2); }
    int main()
    {
        //sigaction(SIGSEGV,&(struct sigaction){.sa_handler=h}, 0); //won't reset the handler, will likely loop
        sigaction(SIGSEGV,&(struct sigaction){.sa_handler=h,.sa_flags=SA_RESETHAND}, 0); //will reset the handler
        //signal(SIGSEGV,h); //may or may not reset the handler
        *a=1;
        return 0;
    }