aboutsummaryrefslogtreecommitdiffstats
path: root/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/signal.c b/signal.c
index 638a0d1483..2876e8706e 100644
--- a/signal.c
+++ b/signal.c
@@ -918,6 +918,7 @@ NOINLINE(static void check_reserved_signal_(const char *name, size_t name_len));
#ifdef SIGBUS
+static sighandler_t default_sigbus_handler;
NORETURN(static ruby_sigaction_t sigbus);
static RETSIGTYPE
@@ -933,12 +934,13 @@ sigbus(int sig SIGINFO_ARG)
#if defined __APPLE__ || defined __linux__
CHECK_STACK_OVERFLOW();
#endif
- rb_bug_for_fatal_signal(SIGINFO_CTX, "Bus Error" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigbus_handler, sig, SIGINFO_CTX, "Bus Error" MESSAGE_FAULT_ADDRESS);
}
#endif
#ifdef SIGSEGV
+static sighandler_t default_sigsegv_handler;
NORETURN(static ruby_sigaction_t sigsegv);
static RETSIGTYPE
@@ -946,12 +948,13 @@ sigsegv(int sig SIGINFO_ARG)
{
check_reserved_signal("SEGV");
CHECK_STACK_OVERFLOW();
- rb_bug_for_fatal_signal(SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigsegv_handler, sig, SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
}
#endif
#ifdef SIGILL
+static sighandler_t default_sigill_handler;
NORETURN(static ruby_sigaction_t sigill);
static RETSIGTYPE
@@ -961,7 +964,7 @@ sigill(int sig SIGINFO_ARG)
#if defined __APPLE__
CHECK_STACK_OVERFLOW();
#endif
- rb_bug_for_fatal_signal(SIGINFO_CTX, "Illegal instruction" MESSAGE_FAULT_ADDRESS);
+ rb_bug_for_fatal_signal(default_sigill_handler, sig, SIGINFO_CTX, "Illegal instruction" MESSAGE_FAULT_ADDRESS);
}
#endif
@@ -1432,21 +1435,28 @@ sig_list(VALUE _)
perror(failed); \
} while (0)
static int
-install_sighandler(int signum, sighandler_t handler)
+install_sighandler_core(int signum, sighandler_t handler, sighandler_t *old_handler)
{
sighandler_t old;
old = ruby_signal(signum, handler);
if (old == SIG_ERR) return -1;
- /* signal handler should be inherited during exec. */
- if (old != SIG_DFL) {
- ruby_signal(signum, old);
+ if (old_handler) {
+ *old_handler = (old == SIG_DFL || old == SIG_IGN) ? 0 : old;
+ }
+ else {
+ /* signal handler should be inherited during exec. */
+ if (old != SIG_DFL) {
+ ruby_signal(signum, old);
+ }
}
return 0;
}
# define install_sighandler(signum, handler) \
- INSTALL_SIGHANDLER(install_sighandler(signum, handler), #signum, signum)
+ INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, NULL), #signum, signum)
+# define force_install_sighandler(signum, handler, old_handler) \
+ INSTALL_SIGHANDLER(install_sighandler_core(signum, handler, old_handler), #signum, signum)
#if RUBY_SIGCHLD
static int
@@ -1558,14 +1568,14 @@ Init_signal(void)
if (!ruby_enable_coredump) {
#ifdef SIGBUS
- install_sighandler(SIGBUS, (sighandler_t)sigbus);
+ force_install_sighandler(SIGBUS, (sighandler_t)sigbus, &default_sigbus_handler);
#endif
#ifdef SIGILL
- install_sighandler(SIGILL, (sighandler_t)sigill);
+ force_install_sighandler(SIGILL, (sighandler_t)sigill, &default_sigill_handler);
#endif
#ifdef SIGSEGV
RB_ALTSTACK_INIT(GET_VM()->main_altstack);
- install_sighandler(SIGSEGV, (sighandler_t)sigsegv);
+ force_install_sighandler(SIGSEGV, (sighandler_t)sigsegv, &default_sigsegv_handler);
#endif
}
#ifdef SIGPIPE