diff --git a/common/base/Init.cpp b/common/base/Init.cpp index 785316d37a..bd1d88f6ec 100644 --- a/common/base/Init.cpp +++ b/common/base/Init.cpp @@ -36,6 +36,7 @@ #include #endif +#include #include #include #include @@ -74,13 +75,12 @@ using std::cout; using std::endl; using std::string; -#if HAVE_DECL_RLIMIT_RTTIME /* * @private - * @brief Print a stack trace if we exceed CPU time. + * @brief Print a stack trace. */ -static void _SIGXCPU_Handler(OLA_UNUSED int signal) { - cout << "Received SIGXCPU" << endl; +static void _DumpStackAndExit(int sig) { + cout << "Received " << strsignal(sig) << endl; #ifdef HAVE_EXECINFO_H enum {STACK_SIZE = 64}; void *array[STACK_SIZE]; @@ -90,7 +90,6 @@ static void _SIGXCPU_Handler(OLA_UNUSED int signal) { #endif exit(ola::EXIT_SOFTWARE); } -#endif bool SetThreadScheduling() { string policy_str = FLAGS_scheduler_policy.str(); @@ -163,8 +162,7 @@ bool SetThreadScheduling() { return false; } - if (!ola::InstallSignal(SIGXCPU, _SIGXCPU_Handler)) { - OLA_WARN << "Failed to install signal SIGXCPU"; + if (!ola::InstallSignal(SIGXCPU, _DumpStackAndExit)) { return false; } #endif @@ -183,22 +181,6 @@ using std::cout; using std::endl; using std::string; -/** - * @private - * Print a stack trace on seg fault. - */ -static void _SIGSEGV_Handler(OLA_UNUSED int signal) { - cout << "Received SIGSEGV or SIGBUS" << endl; - #ifdef HAVE_EXECINFO_H - enum {STACK_SIZE = 64}; - void *array[STACK_SIZE]; - size_t size = backtrace(array, STACK_SIZE); - - backtrace_symbols_fd(array, size, STDERR_FILENO); - #endif - exit(EXIT_SOFTWARE); -} - bool ServerInit(int argc, char *argv[], ExportMap *export_map) { ola::math::InitRandom(); if (!InstallSEGVHandler()) @@ -209,7 +191,6 @@ bool ServerInit(int argc, char *argv[], ExportMap *export_map) { return SetThreadScheduling() && NetworkInit(); } - bool ServerInit(int *argc, char *argv[], ExportMap *export_map, @@ -263,10 +244,10 @@ bool NetworkInit() { #endif } -bool InstallSignal(int signal, void(*fp)(int signo)) { +bool InstallSignal(int sig, void(*fp)(int signo)) { #ifdef _WIN32 - if (::signal(signal, fp) == SIG_ERR) { - OLA_WARN << "Failed to install signal for " << signal; + if (::signal(sig, fp) == SIG_ERR) { + OLA_WARN << "signal(" << strsignal(sig) << ": " << strerror(errno); return false; } #else @@ -275,8 +256,8 @@ bool InstallSignal(int signal, void(*fp)(int signo)) { sigemptyset(&action.sa_mask); action.sa_flags = 0; - if (sigaction(signal, &action, NULL) < 0) { - OLA_WARN << "Failed to install signal for " << signal; + if (sigaction(sig, &action, NULL) < 0) { + OLA_WARN << "sigaction(" << strsignal(sig) << ": " << strerror(errno); return false; } #endif // _WIN32 @@ -285,13 +266,11 @@ bool InstallSignal(int signal, void(*fp)(int signo)) { bool InstallSEGVHandler() { #ifndef _WIN32 - if (!InstallSignal(SIGBUS, _SIGSEGV_Handler)) { - OLA_WARN << "Failed to install signal SIGBUS"; + if (!InstallSignal(SIGBUS, _DumpStackAndExit)) { return false; } #endif // !_WIN32 - if (!InstallSignal(SIGSEGV, _SIGSEGV_Handler)) { - OLA_WARN << "Failed to install signal SIGSEGV"; + if (!InstallSignal(SIGSEGV, _DumpStackAndExit)) { return false; } return true; diff --git a/examples/ola-uni-stats.cpp b/examples/ola-uni-stats.cpp index 4ecfda1a7c..13166c8b41 100644 --- a/examples/ola-uni-stats.cpp +++ b/examples/ola-uni-stats.cpp @@ -234,10 +234,12 @@ void UniverseTracker::RegisterComplete(const string &error) { SelectServer *ss = NULL; -static void InteruptSignal(int unused) { - if (ss) +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; + if (ss) { ss->Terminate(); - (void) unused; + } + errno = old_errno; } diff --git a/tools/e133/basic-controller.cpp b/tools/e133/basic-controller.cpp index 942c3be69e..108ee7fb1c 100644 --- a/tools/e133/basic-controller.cpp +++ b/tools/e133/basic-controller.cpp @@ -20,6 +20,7 @@ * I'm using this for scale testing. */ +#include #include #include #include @@ -293,10 +294,12 @@ void SimpleE133Controller::SocketClosed(IPV4SocketAddress peer) { /** * Interupt handler */ -static void InteruptSignal(int unused) { - if (controller) +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; + if (controller) { controller->Stop(); - (void) unused; + } + errno = old_errno; } int main(int argc, char *argv[]) { diff --git a/tools/e133/basic-device.cpp b/tools/e133/basic-device.cpp index 7c87e698bf..4777169481 100644 --- a/tools/e133/basic-device.cpp +++ b/tools/e133/basic-device.cpp @@ -20,6 +20,7 @@ * I'm using this for scale testing. */ +#include #include #include #include @@ -185,10 +186,12 @@ SimpleE133Device *device = NULL; /** * Interupt handler */ -static void InteruptSignal(int unused) { - if (device) +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; + if (device) { device->Stop(); - (void) unused; + } + errno = old_errno; } int main(int argc, char *argv[]) { diff --git a/tools/e133/e133-receiver.cpp b/tools/e133/e133-receiver.cpp index ef5f71204b..cd60921ea7 100644 --- a/tools/e133/e133-receiver.cpp +++ b/tools/e133/e133-receiver.cpp @@ -24,6 +24,7 @@ #include #endif +#include #include #include @@ -83,10 +84,12 @@ SimpleE133Node *simple_node; /* * Terminate cleanly on interrupt. */ -static void InteruptSignal(int signo) { - if (simple_node) +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; + if (simple_node) { simple_node->Stop(); - (void) signo; + } + errno = old_errno; } void HandleTriDMX(DmxBuffer *buffer, DmxTriWidget *widget) { diff --git a/tools/ola_trigger/ola-trigger.cpp b/tools/ola_trigger/ola-trigger.cpp index b4ffa27678..c73730a5d1 100644 --- a/tools/ola_trigger/ola-trigger.cpp +++ b/tools/ola_trigger/ola-trigger.cpp @@ -78,9 +78,11 @@ typedef vector SlotList; #ifndef _WIN32 static void CatchSIGCHLD(OLA_UNUSED int signo) { pid_t pid; + int old_errno = errno; do { pid = waitpid(-1, NULL, WNOHANG); } while (pid > 0); + errno = old_errno; } #endif @@ -91,9 +93,11 @@ static void CatchSIGCHLD(OLA_UNUSED int signo) { static void CatchSIGINT(OLA_UNUSED int signo) { // there is a race condition here if you send the signal before we call Run() // it's not a huge deal though. + int old_errno = errno; if (ss) { ss->Terminate(); } + errno = old_errno; } @@ -101,39 +105,14 @@ static void CatchSIGINT(OLA_UNUSED int signo) { * Install the SIGCHLD handler. */ bool InstallSignals() { -#ifdef WIN32 +#ifndef WIN32 // There's no SIGCHILD on Windows - if (signal(SIGINT, CatchSIGINT) == reinterpret_cast(EINVAL)) { - OLA_WARN << "Failed to install signal SIGINT"; - return false; - } - if (signal(SIGTERM, CatchSIGINT) == reinterpret_cast(EINVAL)) { - OLA_WARN << "Failed to install signal SIGTERM"; - return false; - } -#else - struct sigaction act, oact; - - act.sa_handler = CatchSIGCHLD; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - - if (sigaction(SIGCHLD, &act, &oact) < 0) { - OLA_WARN << "Failed to install signal SIGCHLD"; - return false; - } - - act.sa_handler = CatchSIGINT; - if (sigaction(SIGINT, &act, &oact) < 0) { - OLA_WARN << "Failed to install signal SIGINT"; - return false; - } - if (sigaction(SIGTERM, &act, &oact) < 0) { - OLA_WARN << "Failed to install signal SIGTERM"; + if (!ola::InstallSignal(SIGCHLD, CatchSIGCHLD)) { return false; } #endif - return true; + return ola::InstallSignal(SIGINT, CatchSIGINT) && + ola::InstallSignal(SIGTERM, CatchSIGINT); }