]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/common: explicitly reraise handled signal in FatalSignal.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 6 Sep 2021 14:39:19 +0000 (14:39 +0000)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 6 Sep 2021 14:46:52 +0000 (14:46 +0000)
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 <rzarzyns@redhat.com>
src/crimson/common/fatal_signal.cc

index 30de30b96cff05b210b874d2e58197726613f8d6..bda460674a8e06f7faf99415725076fc02b9b5a7 100644 (file)
@@ -32,6 +32,23 @@ void FatalSignal::install_oneshot_signals_handler()
   (install_oneshot_signal_handler<SigNums>() , ...);
 }
 
+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 <int SigNum>
 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;
   }