2

I have added a sighandler for SIGABRT signal.

The default behavior of abort() is to generate a core-dump.

I would like to do the same in signal handler but before crashing, execute cleanup code.

I have tried as below and I know that below piece of code is not going to work.

static void
proc_sigabort_handler (int signo UNUSED)
{
    /* cleanup */
    abort(); /* This is to coredump */
}

signal(SIGABRT, proc_sigabort_handler);

Problem: abort() call in sighandler raises SIGABRT signal and end up in same sighandler function and this goes on.

Is there any syscall similar to abort() to generate a core-dump?

Edit after some replies:

user@srv1 ~/linux>  uname -a

Linux srv1 2.4.21-63.ELsmp #1 SMP Wed Oct 28 23:15:46 EDT 2009 i686 i686 i386 GNU/Linux

Linux abort(3) man Page:

If the SIGABRT signal is ignored, or caught by a handler that returns, the abort() function will still terminate the process. It does this by restoring the default disposition for SIGABRT and then raising the signal for a second time.

Ex:

void mysigabort()
{
    printf("I caught the SIGABRT signal!\n");/* I know that printf should be avoided */
    return;    
} 

int main()
{
    signal(SIGABRT, mysigabort);

    while(1);  /* infinite loop */

    exit(0);
}

Produces:

user@srv1 ~/linux>  ./a.out

I caught the SIGABRT signal!

<cursor>


user@srv1 ~/linux>  kill -6 25208

No cores found. Even process is not terminated.

If there is no user-defined signal handler, core is generated.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
Ram
  • 1,153
  • 4
  • 16
  • 34
  • I believe (correct me if I'm wrong) that it is a good idea to `fflush(stdout);` after that print in your `SIGABRT` handler to ensure the statement is printed. – RastaJedi Feb 03 '17 at 00:57

2 Answers2

4

You may restore the default SIGABRT behavior before catching it the second time :

void mysigabort(int signum)
{
    // whatever you want
    signal(signum, SIG_DFL);
    kill(getpid(), signum); // or abort() ?
}
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
2

From the abort man-page on Linux:

If the SIGABRT signal is ignored, or caught by a handler that returns, the abort() function will still terminate the process. It does this by restoring the default dis‐ position for SIGABRT and then raising the signal for a second time.

OP Ram pointed out that this is Linux-specific, but there, you can simply return from your signal handler - there is no need to call abort() a second time. libc's abort() will take care of the rest.

Community
  • 1
  • 1
Phillip
  • 13,448
  • 29
  • 41
  • I have tried the same. It does not seem to be doing that in BSD. – Ram May 19 '14 at 11:58
  • 2
    Linux man page: http://linux.die.net/man/3/abort BSD man page: http://www.freebsd.org/cgi/man.cgi?query=abort&sektion=3 – Ram May 19 '14 at 11:58
  • Even if SIGABRT is raised for the second time, we do endup in same sighandler function. – Ram May 19 '14 at 12:02
  • I quickly tested it, second time SIGABRT did not enter into signal-handler but still there is no crash generated and pid of proc is still the same. – Ram May 19 '14 at 12:07
  • Interesting. The Linux manpage doesn't mention that this is Linux specific. I've added that, thanks! As I've said, it's the `abort()` implementation which takes care of calling the handler a second time. In your test case, you've sent the SIGABRT signal by other means. Try calling `abort()` in place of your infinite `while` loop. (It's save to assume that a library function would use the libc `abort()`.) Of course, this does not solve the platform dependance problem. – Phillip May 19 '14 at 13:15
  • Try calling abort() in place of your infinite while loop. Yes this works, but that is not what I want to do. In case if process gets SIBABRT (signal 6) from external sources, in program sigabrt handler, I would like to clean up few things and then abort (core-dump). adding abort() in main function is not going to solve what I am looking for. I have added abort() in mysigabort() function, and sent kill -6 to process. But this one resulted in multiple printfs and finally core. I don't want this too. After printf() in sighandler, just generate core-dump. – Ram May 20 '14 at 05:38
  • 1
    External sources will in almost all cases use `abort()` rather than just sending the signal, that's what I wanted to say. (If you only want to solve your problem, you could also call `signal(SIGABRT, SIG_DFL)` before calling `abort()` from the signal handler. But I don't know how portable that is either..) – Phillip May 20 '14 at 08:01
  • 1
    Yes, it works after resetting handler to default. signal(SIGABRT, SIG_DFL); then abort(); This looks like a workaround. It does not seem to be behaving as man page says. According to man page, SIGABRT should have terminated and generated core-dump even if there is a user-defined sigabrt handler. Anyways, this is resolved now. Thanks. – Ram May 20 '14 at 09:49