From 5a6e58e1621eae543b5f65a606c18e2dddb84a26 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 8 Sep 2020 13:44:44 +0800 Subject: [PATCH] crimson/osd: handle fatal signals 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 (cherry picked from commit 6e26243b6db49bb9813f8b8aeade68da07dc6065) Conflicts: src/crimson/osd/main.cc --- src/crimson/CMakeLists.txt | 1 + src/crimson/common/fatal_signal.cc | 62 ++++++++++++++++++++++++++++++ src/crimson/common/fatal_signal.h | 16 ++++++++ src/crimson/osd/main.cc | 2 + 4 files changed, 81 insertions(+) create mode 100644 src/crimson/common/fatal_signal.cc create mode 100644 src/crimson/common/fatal_signal.h diff --git a/src/crimson/CMakeLists.txt b/src/crimson/CMakeLists.txt index c798391d8711b..c58161f267b10 100644 --- a/src/crimson/CMakeLists.txt +++ b/src/crimson/CMakeLists.txt @@ -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 index 0000000000000..324bbb6786bbe --- /dev/null +++ b/src/crimson/common/fatal_signal.cc @@ -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 +#include +#include + +#include + +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 index 0000000000000..8320f99d69050 --- /dev/null +++ b/src/crimson/common/fatal_signal.h @@ -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 + +class FatalSignal { +public: + FatalSignal(); + +private: + void signaled(int signum); + static void print_backtrace(int signum); + std::atomic handled = false; +}; diff --git a/src/crimson/osd/main.cc b/src/crimson/osd/main.cc index d4e72c29c1ec7..fd80c84ac252d 100644 --- a/src/crimson/osd/main.cc +++ b/src/crimson/osd/main.cc @@ -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 -- 2.39.5