Skip to content

Commit 43db733

Browse files
authored
Merge pull request ceph#63673 from Matan-B/wip-matanb-crimson-signals-aborts
crimson/common/fatal_signal: Rework signals Reviewed-by: Yingxin Cheng <[email protected]>
2 parents 6d060ba + ec75b36 commit 43db733

File tree

3 files changed

+55
-42
lines changed

3 files changed

+55
-42
lines changed

src/crimson/common/assert.cc

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "crimson/common/log.h"
1010

11+
SET_SUBSYS(osd);
12+
1113
namespace ceph {
1214
[[gnu::cold]] void __ceph_assert_fail(const ceph::assert_data &ctx)
1315
{
@@ -18,12 +20,8 @@ namespace ceph {
1820
const char* file, int line,
1921
const char* func)
2022
{
21-
seastar::logger& logger = crimson::get_logger(0);
22-
logger.error("{}:{} : In function '{}', ceph_assert(%s)\n"
23-
"{}",
24-
file, line, func, assertion,
25-
seastar::current_backtrace());
26-
std::cout << std::flush;
23+
GENERIC_ERROR("{}:{} : In function '{}', ceph_assert({})\n",
24+
file, line, func, assertion);
2725
abort();
2826
}
2927
[[gnu::cold]] void __ceph_assertf_fail(const char *assertion,
@@ -37,25 +35,15 @@ namespace ceph {
3735
std::vsnprintf(buf, sizeof(buf), msg, args);
3836
va_end(args);
3937

40-
seastar::logger& logger = crimson::get_logger(0);
41-
logger.error("{}:{} : In function '{}', ceph_assert(%s)\n"
42-
"{}\n{}\n",
43-
file, line, func, assertion,
44-
buf,
45-
seastar::current_backtrace());
46-
std::cout << std::flush;
38+
GENERIC_ERROR("{}:{} : In function '{}', ceph_assert({})\n {}\n",
39+
file, line, func, assertion, buf);
4740
abort();
4841
}
4942

5043
[[gnu::cold]] void __ceph_abort(const char* file, int line,
5144
const char* func, const std::string& msg)
5245
{
53-
seastar::logger& logger = crimson::get_logger(0);
54-
logger.error("{}:{} : In function '{}', abort(%s)\n"
55-
"{}",
56-
file, line, func, msg,
57-
seastar::current_backtrace());
58-
std::cout << std::flush;
46+
GENERIC_ERROR("{}:{} : In function '{}', abort({})\n", file, line, func, msg);
5947
abort();
6048
}
6149

@@ -69,12 +57,8 @@ namespace ceph {
6957
std::vsnprintf(buf, sizeof(buf), fmt, args);
7058
va_end(args);
7159

72-
seastar::logger& logger = crimson::get_logger(0);
73-
logger.error("{}:{} : In function '{}', abort()\n"
74-
"{}\n{}\n",
75-
file, line, func,
76-
buf,
77-
seastar::current_backtrace());
60+
GENERIC_ERROR("{}:{} : In function '{}', abort()\n {}\n",
61+
file, line, func, buf);
7862
std::cout << std::flush;
7963
abort();
8064
}

src/crimson/common/fatal_signal.cc

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,23 @@
77
#include <iostream>
88
#include <string_view>
99

10+
// boost is able to translate addresses
11+
// to lines with the following definition.
12+
// Similar to Seastar's seastar-addr2line
1013
#define BOOST_STACKTRACE_USE_ADDR2LINE
14+
15+
// Consider std once C++23 is available
1116
#include <boost/stacktrace.hpp>
17+
1218
#include <seastar/core/reactor.hh>
1319

20+
#include "crimson/common/log.h"
21+
1422
#include "common/safe_io.h"
1523
#include "include/scope_guard.h"
1624

25+
SET_SUBSYS(osd);
26+
1727
FatalSignal::FatalSignal()
1828
{
1929
install_oneshot_signals_handler<SIGSEGV,
@@ -78,27 +88,40 @@ void FatalSignal::install_oneshot_signal_handler()
7888
assert(r == 0);
7989
}
8090

81-
8291
[[gnu::noinline]] static void print_backtrace(std::string_view cause) {
83-
std::cerr << cause;
84-
if (seastar::engine_is_ready()) {
85-
std::cerr << " on shard " << seastar::this_shard_id();
86-
}
8792
// nobody wants to see things like `FatalSignal::signaled()` or
8893
// `print_backtrace()` in our backtraces. `+ 1` is for the extra
8994
// frame created by kernel (signal trampoline, it will take care
9095
// about e.g. sigreturn(2) calling; see the man page).
91-
constexpr std::size_t FRAMES_TO_SKIP = 3 + 1;
92-
std::cerr << ".\nBacktrace:\n";
93-
std::cerr << boost::stacktrace::stacktrace(
96+
constexpr std::size_t FRAMES_TO_SKIP = 2 + 1;
97+
98+
// Let's inform regarding the abort before getting the stacktrace
99+
std::string pre_backtrace = fmt::format(
100+
"Aborting {} on shard {} - Stopping all shards",
101+
cause,
102+
seastar::engine_is_ready() ? std::to_string(seastar::this_shard_id()) : "no shard");
103+
104+
GENERIC_ERROR("{}", pre_backtrace);
105+
std::cerr << pre_backtrace << std::flush;
106+
107+
seastar::engine().exit(1);
108+
109+
std::string backtrace = fmt::format("{} on shard {} \nBacktrace:\n {}",
110+
cause,
111+
seastar::engine_is_ready() ? std::to_string(seastar::this_shard_id()) : "no shard",
112+
boost::stacktrace::to_string(boost::stacktrace::stacktrace(
94113
FRAMES_TO_SKIP,
95-
static_cast<std::size_t>(-1)/* max depth same as the default one */);
96-
std::cerr << std::flush;
114+
static_cast<std::size_t>(-1)/* max depth same as the default one */)));
115+
116+
// Print backtrace in log and in std out
117+
GENERIC_ERROR("{}", backtrace);
118+
std::cerr << backtrace << std::flush;
119+
97120
// TODO: dump crash related meta data to $crash_dir
98121
// see handle_fatal_signal()
99122
}
100123

101-
static void print_segv_info(const siginfo_t& siginfo)
124+
[[maybe_unused]] static void print_segv_info(const siginfo_t& siginfo)
102125
{
103126
std::cerr \
104127
<< "Dump of siginfo:" << std::endl
@@ -127,7 +150,7 @@ static void print_segv_info(const siginfo_t& siginfo)
127150
std::cerr << std::flush;
128151
}
129152

130-
static void print_proc_maps()
153+
[[maybe_unused]] static void print_proc_maps()
131154
{
132155
const int fd = ::open("/proc/self/maps", O_RDONLY);
133156
if (fd < 0) {
@@ -156,17 +179,20 @@ static void print_proc_maps()
156179
[[gnu::noinline]] void FatalSignal::signaled(const int signum,
157180
const siginfo_t& siginfo)
158181
{
182+
// Commented out for clean backtrace logs,
183+
// can be used if needed:
184+
// print_proc_maps();
185+
// print_segv_info(siginfo);
186+
159187
switch (signum) {
160188
case SIGSEGV:
161-
print_backtrace("Segmentation fault");
162-
print_segv_info(siginfo);
189+
print_backtrace("Got SIGSEGV");
163190
break;
164191
case SIGABRT:
165-
print_backtrace("Aborting");
192+
print_backtrace("Got SIGABRT");
166193
break;
167194
default:
168-
print_backtrace(fmt::format("Signal {}", signum));
195+
print_backtrace(fmt::format("Got signal {}", signum));
169196
break;
170197
}
171-
print_proc_maps();
172198
}

src/crimson/common/log.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ static inline seastar::log_level to_log_level(int level) {
4848
#define LOGGER(subname_) crimson::get_logger(ceph_subsys_##subname_)
4949
#define LOG_PREFIX(x) constexpr auto FNAME = #x
5050

51+
#define GENERIC_LOG(level_, MSG, ...) \
52+
LOCAL_LOGGER.log(level_, MSG , ##__VA_ARGS__)
5153
#define LOG(level_, MSG, ...) \
5254
LOCAL_LOGGER.log(level_, "{}: " MSG, FNAME , ##__VA_ARGS__)
5355
#define SUBLOG(subname_, level_, MSG, ...) \
@@ -80,6 +82,7 @@ static inline seastar::log_level to_log_level(int level) {
8082
#define SUBWARNI(subname_, ...) SUBLOGI(subname_, seastar::log_level::warn, __VA_ARGS__)
8183

8284
#define ERROR(...) LOG(seastar::log_level::error, __VA_ARGS__)
85+
#define GENERIC_ERROR(...) GENERIC_LOG(seastar::log_level::error, __VA_ARGS__)
8386
#define ERRORI(...) LOGI(seastar::log_level::error, __VA_ARGS__)
8487
#define SUBERROR(subname_, ...) SUBLOG(subname_, seastar::log_level::error, __VA_ARGS__)
8588
#define SUBERRORI(subname_, ...) SUBLOGI(subname_, seastar::log_level::error, __VA_ARGS__)

0 commit comments

Comments
 (0)