Issue
Function called from signal handler not asynchronous-safe
(strict) occurs when a signal handler calls a function that is not
asynchronous-safe according to the C standard. An asynchronous-safe function can be
interrupted at any point in its execution, then called again without causing an inconsistent
state. It can also correctly handle global data that might be in an inconsistent state.
When you select the checker Function called from signal handler not
asynchronous-safe, the checker detects calls to functions that are not
asynchronous-safe according to the POSIX standard. Function called from
signal handler not asynchronous-safe (strict) does not raise a defect for these
cases. Function called from signal handler not asynchronous-safe
(strict) raises a defect for functions that are asynchronous-safe according to
the POSIX standard but not according to the C standard.
If a signal handler calls another function that calls an asynchronous-unsafe function, the
defect appears on the function call in the signal handler. The defect traceback shows the full
path from the signal handler to the asynchronous-unsafe function.
RiskWhen a signal handler is invoked, the execution of the program is interrupted. After the
handler is finished, program execution resumes at the point of interruption. If a function
is executing at the time of the interruption, calling it from within the signal handler is
undefined behavior, unless it is asynchronous-safe.
FixThe C standard defines the following functions as asynchronous-safe. You can call these
functions from a signal handler:
abort()
_Exit()
quick_exit()
signal()
Example - Call to raise() Inside Signal Handler#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <syslog.h>
#include <unistd.h>
void SIG_ERR_handler(int signum)
{
int s0 = signum;
/* SIGTERM specific handling */
}
void sig_handler(int signum)
{
int s0 = signum;
/* Call raise() */
if (raise(SIGTERM) != 0) {
/* Handle error */
}
}
int finc(void)
{
if (signal(SIGTERM, SIG_ERR_handler) == SIG_ERR)
{
/* Handle error */
}
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
/* Handle error */
}
/* Program code */
if (raise(SIGINT) != 0)
{
/* Handle error */
}
/* More code */
return 0;
}
In this example, sig_handler calls raise() when
catching a signal. If the handler catches another signal while raise() is
executing, the behavior of the program is undefined.
Correction — Remove Call to raise() in Signal HandlerAccording to the C standard, the only functions that you can safely call from a signal
handler are abort(), _Exit(),
quick_exit(), and signal().
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <syslog.h>
#include <unistd.h>
void SIG_ERR_handler(int signum)
{
int s0 = signum;
/* SIGTERM specific handling */
}
void sig_handler(int signum)
{
int s0 = signum;
}
int func(void)
{
if (signal(SIGTERM, SIG_ERR_handler) == SIG_ERR)
{
/* Handle error */
}
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
/* Handle error */
}
/* Program code */
if (raise(SIGINT) != 0)
{
/* Handle error */
}
/* More code */
return 0;
}