mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
spi-hdlc-adapter: Don't call syslog() or fprintf() from signal handlers. (#339)
`syslog()` and `fprintf()` are not async-signal-safe. They can (and do) cause deadlocks under various circumstances. This change replaces the calls to these functions with calls to `write()`. It also adds a watchdog of sorts to the `signal_critical()` handler to make sure that even if we call some functions that are not async-signal-safe that we will at least terminate eventually.
This commit is contained in:
committed by
Jonathan Hui
parent
3a694016a1
commit
6587132ff2
@@ -101,6 +101,9 @@ enum {
|
||||
MODE_PTY = 1,
|
||||
};
|
||||
|
||||
// Ignores return value from function 's'
|
||||
#define IGNORE_RETURN_VALUE(s) do { if (s){} } while (0)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* MARK: Global State */
|
||||
|
||||
@@ -153,8 +156,13 @@ static sig_t sPreviousHandlerForSIGTERM;
|
||||
|
||||
static void signal_SIGINT(int sig)
|
||||
{
|
||||
static const char message[] = "\nCaught SIGINT!\n";
|
||||
|
||||
sRet = EXIT_QUIT;
|
||||
syslog(LOG_NOTICE, "Caught SIGINT!");
|
||||
|
||||
// Can't use syslog() because it isn't async signal safe.
|
||||
// So we write to stderr
|
||||
IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
|
||||
|
||||
// Restore the previous handler so that if we end up getting
|
||||
// this signal again we peform the system default action.
|
||||
@@ -166,8 +174,13 @@ static void signal_SIGINT(int sig)
|
||||
|
||||
static void signal_SIGTERM(int sig)
|
||||
{
|
||||
static const char message[] = "\nCaught SIGTERM!\n";
|
||||
|
||||
sRet = EXIT_QUIT;
|
||||
syslog(LOG_NOTICE, "Caught SIGTERM!");
|
||||
|
||||
// Can't use syslog() because it isn't async signal safe.
|
||||
// So we write to stderr
|
||||
IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
|
||||
|
||||
// Restore the previous handler so that if we end up getting
|
||||
// this signal again we peform the system default action.
|
||||
@@ -178,8 +191,13 @@ static void signal_SIGTERM(int sig)
|
||||
|
||||
static void signal_SIGHUP(int sig)
|
||||
{
|
||||
static const char message[] = "\nCaught SIGHUP!\n";
|
||||
|
||||
sRet = EXIT_FAILURE;
|
||||
syslog(LOG_NOTICE, "Caught SIGHUP!");
|
||||
|
||||
// Can't use syslog() because it isn't async signal safe.
|
||||
// So we write to stderr
|
||||
IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
|
||||
|
||||
// We don't restore the "previous handler"
|
||||
// because we always want to let the main
|
||||
@@ -203,6 +221,16 @@ static void signal_critical(int sig, siginfo_t * info, void * ucontext)
|
||||
(void)uc;
|
||||
(void)info;
|
||||
|
||||
// We call some functions here which aren't async-signal-safe,
|
||||
// but this function isn't really useful without those calls.
|
||||
// Since we are making a gamble (and we deadlock if we loose),
|
||||
// we are going to set up a two-second watchdog to make sure
|
||||
// we end up terminating like we should. The choice of a two
|
||||
// second timeout is entirely arbitrary, and may be changed
|
||||
// if needs warrant.
|
||||
alarm(2);
|
||||
signal(SIGALRM, SIG_DFL);
|
||||
|
||||
fprintf(stderr, " *** FATAL ERROR: Caught signal %d (%s):\n", sig, strsignal(sig));
|
||||
|
||||
stack_depth = backtrace(stack, FAULT_BACKTRACE_STACK_DEPTH);
|
||||
|
||||
Reference in New Issue
Block a user