sigaction's signal handler not called in child process

I've a program, which installs a signal handler for SIGSEGV. In signal handler ( I try to catch crash ) I restart my application.

But when my application is resurrected it doesn't handle SIGSEGV anymore.

Here's an example:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

const char * app = 0;

void sig_handler(int signo)
{
    puts("sig_handler");

    const pid_t p = fork();

    if (p == 0)
    {
        printf("Running app %s\n", app);
        execl(app, 0);
    }

    exit(1);
}


int main(int argc, char** argv)
{
    app = argv[0];

    struct sigaction act;
    sigemptyset(&act.sa_mask);

    act.sa_handler = sig_handler;
    act.sa_flags = 0;

    const int status = sigaction(SIGSEGV, &act, 0) == 0;     
    printf("signaction = %d\n", status);

    sleep(5);

    int* a = 0;
    int b = *a;

    return 0;
}

what I get in output is:

./signals 
signaction = 1
sig_handler
Running app ./signals
signaction = 1

So I can see sighandler was set in right way, but resurrected app simply crashed silently.

What am I missing?

Answers


What you're missing is that, by default, when you handle a signal, any additional delivery of that signal is blocked until the handling function returns. Since you never return from your signal handler (you call execl() instead) then your second SIGSEGV isn't being delivered. It's waiting until your signal handler function returns, which it never will.

To get the results you seem to want, you have to change this default behavior. The easiest way to do that is to set the appropriate flag when you register the signal handler:

act.sa_flags = SA_NODEFER;

and you'll get the recursive behavior you seem to be looking for. Your other option is to unblock it with sigprocmask() before your execl() call.

Couple of other ancillary points:

  1. puts(), printf(), execl() and exit() are not async-safe, and shouldn't be called from a signal handler. execle() and _exit() would be OK.

  2. You're not calling execl() properly. The first argument should be the application name, so execl(app, app, (char *)0); would be correct. The cast to char *, which you omit, is required.


Need Your Help

Retrieving Temporary Access Token using jQuery OAUTH

javascript jquery oauth-2.0 shopify

I am attempting to make an API OAUTH2 call to Shopify to authenticate. When I go to my application, the first screen comes up. I press Install, and then it redirects me back to where I started. The

tinyscrollbar scroll not working in chrome in windows 8.0

jquery

I have machine with chrome installed on Windows 8.0 laptop (which has touchscreen)