ruby-changes:63794
From: Koichi <ko1@a...>
Date: Mon, 30 Nov 2020 05:12:16 +0900 (JST)
Subject: [ruby-changes:63794] 77936ad679 (master): support SIGSEGV/BUS while read_barrier_handler()
https://git.ruby-lang.org/ruby.git/commit/?id=77936ad679 From 77936ad679d63a6d0e7b585db4c31db5507f5586 Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Mon, 30 Nov 2020 05:07:28 +0900 Subject: support SIGSEGV/BUS while read_barrier_handler() read_barrier_handler() can cause SIGSEGV/BUS so it should show the errors. diff --git a/gc.c b/gc.c index 7fe4f8c..ab3f861 100644 --- a/gc.c +++ b/gc.c @@ -4597,18 +4597,25 @@ static struct sigaction old_sigsegv_handler; https://github.com/ruby/ruby/blob/trunk/gc.c#L4597 static void read_barrier_signal(int sig, siginfo_t * info, void * data) { - extern int ruby_on_ci; - if (ruby_on_ci) { // `read_barrier_handler` may crash. Report backtraces first on CI. -# if HAVE_BACKTRACE // `rb_bug_without_die` may crash on `control_frame_dump`. Report a C backtrace first. - fprintf(stderr, "-- C level backtrace (read_barrier_signal) " - "-------------------------------------------\n"); - rb_print_backtrace(); - fprintf(stderr, "\n"); -# endif - extern void rb_bug_without_die(const char *fmt, ...); - rb_bug_without_die("died with read_barrier_signal installed"); - } + // setup SEGV/BUS handlers for errors + struct sigaction prev_sigbus, prev_sigsegv; + sigaction(SIGBUS, &old_sigbus_handler, &prev_sigbus); + sigaction(SIGSEGV, &old_sigsegv_handler, &prev_sigsegv); + + // enable SIGBUS/SEGV + sigset_t set, prev_set; + sigemptyset(&set); + sigaddset(&set, SIGBUS); + sigaddset(&set, SIGSEGV); + sigprocmask(SIG_UNBLOCK, &set, &prev_set); + + // run handler read_barrier_handler((intptr_t)info->si_addr); + + // reset SEGV/BUS handlers + sigaction(SIGBUS, &prev_sigbus, NULL); + sigaction(SIGSEGV, &prev_sigsegv, NULL); + sigprocmask(SIG_SETMASK, &prev_set, NULL); } static void uninstall_handlers(void) -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/