]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: handle fatal signals
authorKefu Chai <kchai@redhat.com>
Tue, 8 Sep 2020 05:44:44 +0000 (13:44 +0800)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 19 Apr 2021 15:24:04 +0000 (15:24 +0000)
seastar sets the signal handler for SIGSEGV and SIGABRT, and its signal
handler prints the stacktrace, but the the stack frames are adresses,
which are not human readable without the help of addr2line.

since crimson is linked with -rdynamic option, we have the symbols added
to the dynamic symbol table already. let print out the symbolized
addresses instead using our own stacktrace utility.

Signed-off-by: Kefu Chai <kchai@redhat.com>
(cherry picked from commit 6e26243b6db49bb9813f8b8aeade68da07dc6065)

 Conflicts:
src/crimson/osd/main.cc

src/crimson/CMakeLists.txt
src/crimson/common/fatal_signal.cc [new file with mode: 0644]
src/crimson/common/fatal_signal.h [new file with mode: 0644]
src/crimson/osd/main.cc

index c798391d8711b1ac55f45f911fde8171d8d1914b..c58161f267b1092e0f7d10874f708b8db766a905 100644 (file)
@@ -15,6 +15,7 @@ set(crimson_common_srcs
   common/assert.cc
   common/buffer_io.cc
   common/config_proxy.cc
+  common/fatal_signal.cc
   common/formatter.cc
   common/perf_counters_collection.cc
   common/log.cc
diff --git a/src/crimson/common/fatal_signal.cc b/src/crimson/common/fatal_signal.cc
new file mode 100644 (file)
index 0000000..324bbb6
--- /dev/null
@@ -0,0 +1,62 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "fatal_signal.h"
+
+#include <signal.h>
+#include <iostream>
+#include <string_view>
+
+#include <seastar/core/reactor.hh>
+
+FatalSignal::FatalSignal()
+{
+  auto fatal_signals = {SIGSEGV,
+                        SIGABRT,
+                        SIGBUS,
+                        SIGILL,
+                        SIGFPE,
+                        SIGXCPU,
+                        SIGXFSZ,
+                        SIGSYS};
+
+  for (auto signum : fatal_signals) {
+    seastar::engine().handle_signal(signum, [signum, this] {
+      signaled(signum);
+    });
+  }
+}
+
+static void print_with_backtrace(std::string_view cause) {
+  std::cerr << cause;
+  if (seastar::engine_is_ready()) {
+    std::cerr << " on shard " << seastar::this_shard_id();
+  }
+  std::cerr << ".\nBacktrace:\n";
+#if 0
+  std::cerr << symbolized::current_backtrace_tasklocal();
+#endif
+  std::cerr << std::flush;
+  // TODO: dump crash related meta data to $crash_dir
+  //       see handle_fatal_signal()
+}
+
+void FatalSignal::signaled(int signum)
+{
+  if (handled.exchange(true)) {
+    return;
+  }
+  switch (signum) {
+  case SIGSEGV:
+    print_with_backtrace("Aborting");
+    break;
+  case SIGABRT:
+    print_with_backtrace("Segmentation fault");
+    break;
+  default:
+    print_with_backtrace(fmt::format("Signal {}", signum));
+    break;
+  }
+  signal(signum, SIG_DFL);
+  seastar::engine().exit(1);
+}
diff --git a/src/crimson/common/fatal_signal.h b/src/crimson/common/fatal_signal.h
new file mode 100644 (file)
index 0000000..8320f99
--- /dev/null
@@ -0,0 +1,16 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <atomic>
+
+class FatalSignal {
+public:
+  FatalSignal();
+
+private:
+  void signaled(int signum);
+  static void print_backtrace(int signum);
+  std::atomic<bool> handled = false;
+};
index d4e72c29c1ec7825eda41fff3b77b7095effa93e..fd80c84ac252d1fff11b7a685d1e4de0cdccb9b2 100644 (file)
@@ -16,6 +16,7 @@
 #include "common/ceph_argparse.h"
 #include "crimson/common/buffer_io.h"
 #include "crimson/common/config_proxy.h"
+#include "crimson/common/fatal_signal.h"
 #include "crimson/mon/MonClient.h"
 #include "crimson/net/Messenger.h"
 #include "global/pidfile.h"
@@ -198,6 +199,7 @@ int main(int argc, char* argv[])
       [&, &ceph_args=ceph_args] {
       auto& config = app.configuration();
       return seastar::async([&] {
+        FatalSignal fatal_signal;
        if (config.count("debug")) {
            seastar::global_logger_registry().set_all_loggers_level(
              seastar::log_level::debug