From 5a73c71dcf4b32c9c30f2cb68bac1d274839488f Mon Sep 17 00:00:00 2001 From: kosaki Date: Sat, 2 Jul 2011 19:59:05 +0000 Subject: * thread_pthread.c (get_stack): add to a care of gurad page on Mac OS X. [Bug #1813] [ruby-core:24540] * signal.c (ruby_signal): SIGBUS use alternative stack too. * signal.c (sigbus): On Mac, thread stack overflow makes SIGBUS instead of SIGSEGV. thus, added stackoverflow check. * signal.c (default_handler): get rid of compilation warning. * signal.c (Init_signal): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32369 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- signal.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'signal.c') diff --git a/signal.c b/signal.c index f02e3db15c..14b7d67344 100644 --- a/signal.c +++ b/signal.c @@ -470,7 +470,7 @@ ruby_signal(int signum, sighandler_t handler) sigact.sa_flags |= SA_NOCLDWAIT; #endif #if defined(SA_ONSTACK) && defined(USE_SIGALTSTACK) - if (signum == SIGSEGV) + if (signum == SIGSEGV || signum == SIGBUS) sigact.sa_flags |= SA_ONSTACK; #endif if (sigaction(signum, &sigact, &old) < 0) { @@ -573,8 +573,21 @@ rb_get_next_signal(void) #ifdef SIGBUS static RETSIGTYPE -sigbus(int sig) +sigbus(int sig SIGINFO_ARG) { +/* + * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page. + * 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); + } +#endif rb_bug("Bus Error"); } #endif @@ -703,7 +716,7 @@ default_handler(int sig) break; #ifdef SIGBUS case SIGBUS: - func = sigbus; + func = (sighandler_t)sigbus; break; #endif #ifdef SIGSEGV @@ -1092,7 +1105,7 @@ Init_signal(void) if (!ruby_enable_coredump) { #ifdef SIGBUS - install_sighandler(SIGBUS, sigbus); + install_sighandler(SIGBUS, (sighandler_t)sigbus); #endif #ifdef SIGSEGV # ifdef USE_SIGALTSTACK -- cgit v1.2.3