Since 1ef66deddfaec1b0654aedd62d484e6f8a186e2c seastar installs
alternative signal handler stack. ASAN also does that and expects
that its stack is still installed when it cleans up, it tries to
unmap current stack.
Fix by restoring previous stack when reactor::run() returns.
Fixes the following error:
==31667==ERROR: AddressSanitizer failed to deallocate 0x2000 (8192) bytes at address 0x625000039900
==31667==AddressSanitizer CHECK failed: ../../../../libsanitizer/sanitizer_common/sanitizer_posix.cc:133 "(("unable to unmap" && 0)) != (0)" (0x0, 0x0)
---
core/reactor.cc | 41 +++++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/core/reactor.cc b/core/reactor.cc
index ee6f59d..56cc7c3 100644
--- a/core/reactor.cc
+++ b/core/reactor.cc
@@ -87,6 +87,7 @@
#endif
#include <xmmintrin.h>
+#include "util/defer.hh"
using namespace std::chrono_literals;
@@ -230,6 +231,30 @@ inline int task_quota_signal() {
return SIGRTMIN + 1;
}
+// Installs signal handler stack for current thread.
+// The stack remains installed as long as the returned object is kept alive.
+// When it goes out of scope the previous handler is restored.
+static decltype(auto) install_signal_handler_stack() {
+ size_t size = SIGSTKSZ;
+ auto mem = std::make_unique<char[]>(size);
+ stack_t stack;
+ stack_t prev_stack;
+ stack.ss_sp = mem.get();
+ stack.ss_flags = 0;
+ stack.ss_size = size;
+ auto r = sigaltstack(&stack, &prev_stack);
+ throw_system_error_on(r == -1);
+ return defer([mem = std::move(mem), prev_stack] () mutable {
+ try {
+ auto r = sigaltstack(&prev_stack, NULL);
+ throw_system_error_on(r == -1);
+ } catch (...) {
+ mem.release(); // We failed to restore previous stack, must leak it.
+ seastar_logger.error("Failed to restore signal stack: {}", std::current_exception());
+ }
+ });
+}
+
reactor::reactor()
: _backend()
#ifdef HAVE_OSV
@@ -2228,6 +2253,8 @@ static void print_backtrace_safe() noexcept {
}
int reactor::run() {
+ auto signal_stack = install_signal_handler_stack();
+
auto collectd_metrics = register_collectd_metrics();
#ifndef HAVE_OSV
@@ -3065,18 +3092,6 @@ void install_oneshot_signal_handler() {
throw_system_error_on(r == -1);
}
-static void install_signal_handler_stack() {
- size_t size = SIGSTKSZ;
- auto mem = std::make_unique<char[]>(size);
- stack_t stack;
- stack.ss_sp = mem.get();
- stack.ss_flags = 0;
- stack.ss_size = size;
- auto r = sigaltstack(&stack, NULL);
- throw_system_error_on(r == -1);
- mem.release();
-}
-
static void print_with_backtrace(const char* cause) noexcept {
print_safe(cause);
if (local_engine) {
@@ -3114,7 +3129,6 @@ void smp::configure(boost::program_options::variables_map configuration)
}
pthread_sigmask(SIG_BLOCK, &sigs, nullptr);
- install_signal_handler_stack();
install_oneshot_signal_handler<SIGSEGV, sigsegv_action>();
install_oneshot_signal_handler<SIGABRT, sigabrt_action>();
install_atomic_signal_handler<SIGQUIT, sigquit_action>();
@@ -3267,7 +3281,6 @@ void smp::configure(boost::program_options::variables_map configuration)
smp::pin(allocation.cpu_id);
}
memory::configure(allocation.mem, hugepages_path);
- install_signal_handler_stack();
sigset_t mask;
sigfillset(&mask);
for (auto sig : { SIGSEGV, SIGQUIT }) {
--
2.5.5