diff options
Diffstat (limited to 'src/mongo/util/signal_handlers_synchronous.cpp')
-rw-r--r-- | src/mongo/util/signal_handlers_synchronous.cpp | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index 9d9e6896c03..67a4e14dd68 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -37,6 +37,7 @@ #include <boost/exception/exception.hpp> #include <csignal> #include <exception> +#include <fmt/format.h> #include <iostream> #include <memory> #include <streambuf> @@ -48,6 +49,7 @@ #include "mongo/platform/compiler.h" #include "mongo/stdx/exception.h" #include "mongo/stdx/thread.h" +#include "mongo/util/assert_util.h" #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/debug_util.h" #include "mongo/util/debugger.h" @@ -265,6 +267,10 @@ void myPureCallHandler() { #else +void abruptQuitAction(int signalNum, siginfo_t*, void*) { + abruptQuit(signalNum); +}; + void abruptQuitWithAddrSignal(int signalNum, siginfo_t* siginfo, void* ucontext_erased) { // For convenient debugger access. MONGO_COMPILER_VARIABLE_UNUSED auto ucontext = static_cast<const ucontext_t*>(ucontext_erased); @@ -298,38 +304,38 @@ void setupSynchronousSignalHandlers() { _set_invalid_parameter_handler(myInvalidParameterHandler); setWindowsUnhandledExceptionFilter(); #else - { - struct sigaction ignoredSignals; - memset(&ignoredSignals, 0, sizeof(ignoredSignals)); - ignoredSignals.sa_handler = SIG_IGN; - sigemptyset(&ignoredSignals.sa_mask); - - invariant(sigaction(SIGHUP, &ignoredSignals, nullptr) == 0); - invariant(sigaction(SIGUSR2, &ignoredSignals, nullptr) == 0); - invariant(sigaction(SIGPIPE, &ignoredSignals, nullptr) == 0); - } - { - struct sigaction plainSignals; - memset(&plainSignals, 0, sizeof(plainSignals)); - plainSignals.sa_handler = abruptQuit; - sigemptyset(&plainSignals.sa_mask); - - // ^\ is the stronger ^C. Log and quit hard without waiting for cleanup. - invariant(sigaction(SIGQUIT, &plainSignals, nullptr) == 0); - - invariant(sigaction(SIGABRT, &plainSignals, nullptr) == 0); - } - { - struct sigaction addrSignals; - memset(&addrSignals, 0, sizeof(addrSignals)); - addrSignals.sa_sigaction = abruptQuitWithAddrSignal; - sigemptyset(&addrSignals.sa_mask); - addrSignals.sa_flags = SA_SIGINFO; - - invariant(sigaction(SIGSEGV, &addrSignals, nullptr) == 0); - invariant(sigaction(SIGBUS, &addrSignals, nullptr) == 0); - invariant(sigaction(SIGILL, &addrSignals, nullptr) == 0); - invariant(sigaction(SIGFPE, &addrSignals, nullptr) == 0); + static constexpr struct { + int signal; + void (*function)(int, siginfo_t*, void*); // signal ignored if nullptr + } kSignalSpecs[] = { + {SIGHUP, nullptr}, + {SIGUSR2, nullptr}, + {SIGPIPE, nullptr}, + {SIGQUIT, &abruptQuitAction}, // sent by '^\'. Log and hard quit, no cleanup. + {SIGABRT, &abruptQuitAction}, + {SIGSEGV, &abruptQuitWithAddrSignal}, + {SIGBUS, &abruptQuitWithAddrSignal}, + {SIGILL, &abruptQuitWithAddrSignal}, + {SIGFPE, &abruptQuitWithAddrSignal}, + }; + for (const auto& spec : kSignalSpecs) { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + if (spec.function == nullptr) { + sa.sa_handler = SIG_IGN; + } else { + sa.sa_sigaction = spec.function; + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + } + if (sigaction(spec.signal, &sa, nullptr) != 0) { + int savedErr = errno; + severe() << format( + FMT_STRING("Failed to install signal handler for signal {} with sigaction: {}"), + spec.signal, + strerror(savedErr)); + fassertFailed(31334); + } } setupSIGTRAPforGDB(); #endif |