From aef1f4bbe53ed0e796fc7b0a31b8914a188d3958 Mon Sep 17 00:00:00 2001 From: Simon Newton Date: Thu, 11 Dec 2014 21:32:11 -0800 Subject: [PATCH 1/3] Clean up signal handling a bit. --- common/base/Init.cpp | 44 ++++++++----------------------- examples/ola-uni-stats.cpp | 6 ++--- tools/e133/basic-controller.cpp | 6 ++--- tools/e133/basic-device.cpp | 6 ++--- tools/e133/e133-receiver.cpp | 6 ++--- tools/ola_trigger/ola-trigger.cpp | 35 +++++------------------- 6 files changed, 29 insertions(+), 74 deletions(-) diff --git a/common/base/Init.cpp b/common/base/Init.cpp index 785316d37a..832edbc19b 100644 --- a/common/base/Init.cpp +++ b/common/base/Init.cpp @@ -74,13 +74,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 +89,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 +161,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 +180,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 +190,6 @@ bool ServerInit(int argc, char *argv[], ExportMap *export_map) { return SetThreadScheduling() && NetworkInit(); } - bool ServerInit(int *argc, char *argv[], ExportMap *export_map, @@ -263,10 +243,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 +255,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 +265,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..84ab2db272 100644 --- a/examples/ola-uni-stats.cpp +++ b/examples/ola-uni-stats.cpp @@ -234,10 +234,10 @@ void UniverseTracker::RegisterComplete(const string &error) { SelectServer *ss = NULL; -static void InteruptSignal(int unused) { - if (ss) +static void InteruptSignal(OLA_UNUSED int sig) { + if (ss) { ss->Terminate(); - (void) unused; + } } diff --git a/tools/e133/basic-controller.cpp b/tools/e133/basic-controller.cpp index 942c3be69e..a316f64a88 100644 --- a/tools/e133/basic-controller.cpp +++ b/tools/e133/basic-controller.cpp @@ -293,10 +293,10 @@ void SimpleE133Controller::SocketClosed(IPV4SocketAddress peer) { /** * Interupt handler */ -static void InteruptSignal(int unused) { - if (controller) +static void InteruptSignal(OLA_UNUSED int unused) { + if (controller) { controller->Stop(); - (void) unused; + } } int main(int argc, char *argv[]) { diff --git a/tools/e133/basic-device.cpp b/tools/e133/basic-device.cpp index 7c87e698bf..370afd1b31 100644 --- a/tools/e133/basic-device.cpp +++ b/tools/e133/basic-device.cpp @@ -185,10 +185,10 @@ SimpleE133Device *device = NULL; /** * Interupt handler */ -static void InteruptSignal(int unused) { - if (device) +static void InteruptSignal(OLA_UNUSED int unused) { + if (device) { device->Stop(); - (void) unused; + } } int main(int argc, char *argv[]) { diff --git a/tools/e133/e133-receiver.cpp b/tools/e133/e133-receiver.cpp index ef5f71204b..6a93a1660d 100644 --- a/tools/e133/e133-receiver.cpp +++ b/tools/e133/e133-receiver.cpp @@ -83,10 +83,10 @@ SimpleE133Node *simple_node; /* * Terminate cleanly on interrupt. */ -static void InteruptSignal(int signo) { - if (simple_node) +static void InteruptSignal(OLA_UNUSED int signo) { + if (simple_node) { simple_node->Stop(); - (void) signo; + } } void HandleTriDMX(DmxBuffer *buffer, DmxTriWidget *widget) { diff --git a/tools/ola_trigger/ola-trigger.cpp b/tools/ola_trigger/ola-trigger.cpp index b4ffa27678..5027136f5c 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 @@ -101,39 +103,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); } From ca832821075ddd0fd8b04765b7d10e951418b97c Mon Sep 17 00:00:00 2001 From: Simon Newton Date: Thu, 11 Dec 2014 21:35:47 -0800 Subject: [PATCH 2/3] Fix the build. --- common/base/Init.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/common/base/Init.cpp b/common/base/Init.cpp index 832edbc19b..bd1d88f6ec 100644 --- a/common/base/Init.cpp +++ b/common/base/Init.cpp @@ -36,6 +36,7 @@ #include #endif +#include #include #include #include From 441b8476ba43eabb1a947fd46a2475de8e733098 Mon Sep 17 00:00:00 2001 From: Simon Newton Date: Fri, 12 Dec 2014 09:04:54 -0800 Subject: [PATCH 3/3] Fix Peter's comments --- examples/ola-uni-stats.cpp | 4 +++- tools/e133/basic-controller.cpp | 5 ++++- tools/e133/basic-device.cpp | 5 ++++- tools/e133/e133-receiver.cpp | 3 +++ tools/ola_trigger/ola-trigger.cpp | 2 ++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/ola-uni-stats.cpp b/examples/ola-uni-stats.cpp index 84ab2db272..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(OLA_UNUSED int sig) { +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; if (ss) { ss->Terminate(); } + errno = old_errno; } diff --git a/tools/e133/basic-controller.cpp b/tools/e133/basic-controller.cpp index a316f64a88..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(OLA_UNUSED int unused) { +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; if (controller) { controller->Stop(); } + errno = old_errno; } int main(int argc, char *argv[]) { diff --git a/tools/e133/basic-device.cpp b/tools/e133/basic-device.cpp index 370afd1b31..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(OLA_UNUSED int unused) { +static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; if (device) { device->Stop(); } + errno = old_errno; } int main(int argc, char *argv[]) { diff --git a/tools/e133/e133-receiver.cpp b/tools/e133/e133-receiver.cpp index 6a93a1660d..cd60921ea7 100644 --- a/tools/e133/e133-receiver.cpp +++ b/tools/e133/e133-receiver.cpp @@ -24,6 +24,7 @@ #include #endif +#include #include #include @@ -84,9 +85,11 @@ SimpleE133Node *simple_node; * Terminate cleanly on interrupt. */ static void InteruptSignal(OLA_UNUSED int signo) { + int old_errno = errno; if (simple_node) { simple_node->Stop(); } + 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 5027136f5c..c73730a5d1 100644 --- a/tools/ola_trigger/ola-trigger.cpp +++ b/tools/ola_trigger/ola-trigger.cpp @@ -93,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; }