Search code examples
clinuxsignalsabort

Is SIGABRT a blockable signal


Consider the simple example below which registers for a signal handler for SIGABRT, then calls abort(). When I run it, the program terminates before printing Done but after async-signal-safe printing in the trapped signal.

This implies that SIGABRT is not a blockable signal. This seems to be supported by this StackOverflow answer. However, I cannot find any corroborating evidence of that behavior in the signal man page, which clearly states that The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored but makes no similar mention for SIGABRT.

Can someone please enlighten me on this behavior?

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

static struct sigaction old_sa;

static void my_handler(int signo)
{
  const char x[] = "In Handler\n";
  write(STDOUT_FILENO, x, strlen(x));
}

int main()
{
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = my_handler;
  sigemptyset(&sa.sa_mask);
  sigaddset(&sa.sa_mask, SIGABRT);
  if (0 != sigaction(SIGABRT, &sa, &old_sa))
  {
    perror("sigaction");
    exit(EXIT_FAILURE);
  }
  printf("Ready\n");

  abort();

  printf("Done\n");
  exit(0);
}

Compiled with gcc ./try.c && ./a.out generates the following output

Ready
In Handler
Aborted

Solution

  • SIGABRT can be blocked. But the abort() function unblocks the signal before sending the signal.

    This is specified in POSIX:

    The abort() function shall override blocking or ignoring the SIGABRT signal.

    You'll get the expected result if you use

    kill(getpid(), SIGABRT);
    

    instead of calling abort()