From: Kefu Chai Date: Tue, 8 Sep 2020 05:44:44 +0000 (+0800) Subject: crimson/osd: handle fatal signals X-Git-Tag: v17.1.0~2192^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=5a6e58e1621eae543b5f65a606c18e2dddb84a26;p=ceph-ci.git 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 --- diff --git a/src/crimson/CMakeLists.txt b/src/crimson/CMakeLists.txt index c798391d871..c58161f267b 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 00000000000..324bbb6786b --- /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 00000000000..8320f99d690 --- /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 d4e72c29c1e..fd80c84ac25 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