From b018f86cd83604cdf23fe0c3b723d0f985e63985 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Mon, 6 Sep 2021 14:39:19 +0000 Subject: [PATCH] crimson/common: explicitly reraise handled signal in FatalSignal. Over the current approach where we just reset the handler to default and allow CPU to re-execute the segfaulting instruction, the explicit `::reraise()` is: 1. immune to a race condition if muliple threads run into troubles the same time; 2. easier to understand and similar to the classic OSD. Signed-off-by: Radoslaw Zarzynski --- src/crimson/common/fatal_signal.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/crimson/common/fatal_signal.cc b/src/crimson/common/fatal_signal.cc index 30de30b96cff0..bda460674a8e0 100644 --- a/src/crimson/common/fatal_signal.cc +++ b/src/crimson/common/fatal_signal.cc @@ -32,6 +32,23 @@ void FatalSignal::install_oneshot_signals_handler() (install_oneshot_signal_handler() , ...); } +static void reraise_fatal(const int signum) +{ + // use default handler to dump core + ::signal(signum, SIG_DFL); + + // normally, we won't get here. if we do, something is very weird. + if (::raise(signum)) { + std::cerr << "reraise_fatal: failed to re-raise signal " << signum + << std::endl; + } else { + std::cerr << "reraise_fatal: default handler for signal " << signum + << " didn't terminate the process?" << std::endl; + } + std::cerr << std::flush; + ::_exit(1); +} + template void FatalSignal::install_oneshot_signal_handler() { @@ -42,10 +59,10 @@ void FatalSignal::install_oneshot_signal_handler() } assert(info); FatalSignal::signaled(signum, *info); - ::signal(signum, SIG_DFL); + reraise_fatal(signum); }; - sigfillset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO | SA_RESTART; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; if constexpr (SigNum == SIGSEGV) { sa.sa_flags |= SA_ONSTACK; } -- 2.39.5