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
CodePudding user response:
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 theSIGABRT
signal.
You'll get the expected result if you use
kill(getpid(), SIGABRT);
instead of calling abort()
CodePudding user response:
Your handler caught the signal. Then it returned. C 2018 7.22.4.1 2 says “The abort
function causes abnormal program termination to occur, unless the signal SIGABRT
is being caught and the signal handler does not return.” So, once your handler returns, the abort
routine continues doing its thing, which is to terminate your program.
If instead of abort();
you use raise(SIGABRT);
to raise the signal without calling the abort
routine, then the signal handler will be called, will print, and will return, after which printf("Done\n");
will be executed.