diff options
author | Michael Leibowitz <michael.leibowitz@intel.com> | 2013-08-15 15:02:54 -0700 |
---|---|---|
committer | Michael Leibowitz <michael.leibowitz@intel.com> | 2013-08-15 15:02:54 -0700 |
commit | 6b0e2a11aeccf2ebc707c22548a0c15c8c2bae06 (patch) | |
tree | d9d59f4b502927634d32832e963db76629ff5a2e /signal.c | |
parent | 3b35de2a90e26b99e2a6d4f61dc56d6ce7ded748 (diff) | |
download | ruby-upstream.tar.gz ruby-upstream.tar.bz2 ruby-upstream.zip |
Imported Upstream version 1.9.3.p448upstream/1.9.3.p448upstream
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 73 |
1 files changed, 48 insertions, 25 deletions
@@ -2,7 +2,7 @@ signal.c - - $Author: kosaki $ + $Author: usa $ created at: Tue Dec 20 10:13:44 JST 1994 Copyright (C) 1993-2007 Yukihiro Matsumoto @@ -16,7 +16,10 @@ #include <signal.h> #include <stdio.h> #include <errno.h> -#include "atomic.h" +#include "ruby_atomic.h" +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif #if !defined(_WIN32) && !defined(HAVE_GCC_ATOMIC_BUILTINS) rb_atomic_t @@ -564,6 +567,23 @@ rb_get_next_signal(void) return sig; } + +#ifdef USE_SIGALTSTACK +static void +check_stack_overflow(const void *addr) +{ + int ruby_stack_overflowed_p(const rb_thread_t *, const void *); + NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); + rb_thread_t *th = GET_THREAD(); + if (ruby_stack_overflowed_p(th, addr)) { + ruby_thread_stack_overflow(th); + } +} +#define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr) +#else +#define CHECK_STACK_OVERFLOW() (void)0 +#endif + #ifdef SIGBUS static RETSIGTYPE sigbus(int sig SIGINFO_ARG) @@ -573,41 +593,44 @@ sigbus(int sig SIGINFO_ARG) * and it's delivered as SIGBUS instaed of SIGSEGV to userland. It's crazy * wrong IMHO. but anyway we have to care it. Sigh. */ -#if defined __MACH__ && defined __APPLE__ && defined USE_SIGALTSTACK - int ruby_stack_overflowed_p(const rb_thread_t *, const void *); - NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); - rb_thread_t *th = GET_THREAD(); - if (ruby_stack_overflowed_p(th, info->si_addr)) { - ruby_thread_stack_overflow(th); - } +#if defined __APPLE__ + CHECK_STACK_OVERFLOW(); #endif rb_bug("Bus Error"); } #endif #ifdef SIGSEGV +static void ruby_abort(void) +{ +#ifdef __sun + /* Solaris's abort() is async signal unsafe. Of course, it is not + * POSIX compliant. + */ + raise(SIGABRT); +#else + abort(); +#endif + +} + static int segv_received = 0; +extern int ruby_disable_gc_stress; + static RETSIGTYPE sigsegv(int sig SIGINFO_ARG) { -#ifdef USE_SIGALTSTACK - int ruby_stack_overflowed_p(const rb_thread_t *, const void *); - NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); - rb_thread_t *th = GET_THREAD(); - if (ruby_stack_overflowed_p(th, info->si_addr)) { - ruby_thread_stack_overflow(th); - } -#endif if (segv_received) { - fprintf(stderr, "SEGV received in SEGV handler\n"); - abort(); - } - else { - extern int ruby_disable_gc_stress; - segv_received = 1; - ruby_disable_gc_stress = 1; - rb_bug("Segmentation fault"); + char msg[] = "SEGV received in SEGV handler\n"; + write(2, msg, sizeof(msg)); + ruby_abort(); } + + CHECK_STACK_OVERFLOW(); + + segv_received = 1; + ruby_disable_gc_stress = 1; + rb_bug("Segmentation fault"); } #endif |