summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-02 19:59:05 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-02 19:59:05 +0000
commit5a73c71dcf4b32c9c30f2cb68bac1d274839488f (patch)
tree466b4390840888688d5b27db87c11db975eab2e5 /signal.c
parent5a31811f411d5baebe94072f779523a139a4ee59 (diff)
* 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
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c21
1 files changed, 17 insertions, 4 deletions
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