[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]