ruby-changes:20321
From: kosaki <ko1@a...>
Date: Sun, 3 Jul 2011 04:59:17 +0900 (JST)
Subject: [ruby-changes:20321] kosaki:r32369 (trunk): * thread_pthread.c (get_stack): add to a care of gurad page on Mac
kosaki 2011-07-03 04:59:05 +0900 (Sun, 03 Jul 2011) New Revision: 32369 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32369 Log: * 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. Modified files: trunk/ChangeLog trunk/signal.c trunk/thread_pthread.c Index: ChangeLog =================================================================== --- ChangeLog (revision 32368) +++ ChangeLog (revision 32369) @@ -1,3 +1,13 @@ +Sun Jul 3 04:50:08 2011 KOSAKI Motohiro <kosaki.motohiro@g...> + + * 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. + Sat Jul 02 08:59:20 2011 Martin Bosslet <Martin.Bosslet@g...> * test/openssl/test_ocsp.rb Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 32368) +++ thread_pthread.c (revision 32369) @@ -458,13 +458,14 @@ { #define CHECK_ERR(expr) \ {int err = (expr); if (err) return err;} -#if defined HAVE_PTHREAD_GETATTR_NP || defined HAVE_PTHREAD_ATTR_GET_NP +#if defined HAVE_PTHREAD_GETATTR_NP || defined HAVE_PTHREAD_ATTR_GET_NP || \ + (defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP) pthread_attr_t attr; size_t guard = 0; # ifdef HAVE_PTHREAD_GETATTR_NP CHECK_ERR(pthread_getattr_np(pthread_self(), &attr)); -# ifdef HAVE_PTHREAD_ATTR_GETSTACK +# ifdef HAVE_PTHREAD_ATTR_GETSTACK /* Linux */ CHECK_ERR(pthread_attr_getstack(&attr, addr, size)); # else CHECK_ERR(pthread_attr_getstackaddr(&attr, addr)); @@ -475,19 +476,20 @@ STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + guard)); *size -= guard; } -# else +# elif defined HAVE_PTHREAD_ATTR_GET_NP /* FreeBSD, DragonFly BSD, NetBSD */ CHECK_ERR(pthread_attr_init(&attr)); CHECK_ERR(pthread_attr_get_np(pthread_self(), &attr)); CHECK_ERR(pthread_attr_getstackaddr(&attr, addr)); CHECK_ERR(pthread_attr_getstacksize(&attr, size)); +# else /* MacOS X */ + pthread_t th = pthread_self(); + *addr = pthread_get_stackaddr_np(th); + *size = pthread_get_stacksize_np(th); + CHECK_ERR(pthread_attr_init(&attr)); # endif CHECK_ERR(pthread_attr_getguardsize(&attr, &guard)); *size -= guard; pthread_attr_destroy(&attr); -#elif defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP - pthread_t th = pthread_self(); - *addr = pthread_get_stackaddr_np(th); - *size = pthread_get_stacksize_np(th); #elif defined HAVE_THR_STKSEGMENT || defined HAVE_PTHREAD_STACKSEG_NP stack_t stk; # if defined HAVE_THR_STKSEGMENT Index: signal.c =================================================================== --- signal.c (revision 32368) +++ signal.c (revision 32369) @@ -470,7 +470,7 @@ 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 @@ #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 @@ break; #ifdef SIGBUS case SIGBUS: - func = sigbus; + func = (sighandler_t)sigbus; break; #endif #ifdef SIGSEGV @@ -1092,7 +1105,7 @@ if (!ruby_enable_coredump) { #ifdef SIGBUS - install_sighandler(SIGBUS, sigbus); + install_sighandler(SIGBUS, (sighandler_t)sigbus); #endif #ifdef SIGSEGV # ifdef USE_SIGALTSTACK -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/