summaryrefslogtreecommitdiff
path: root/src/mongo/util/signal_handlers_synchronous.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/signal_handlers_synchronous.cpp')
-rw-r--r--src/mongo/util/signal_handlers_synchronous.cpp70
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