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

ruby-changes:35896

From: nobu <ko1@a...>
Date: Thu, 16 Oct 2014 17:16:01 +0900 (JST)
Subject: [ruby-changes:35896] nobu:r47977 (trunk): signal.c: abort if nesting reserved signal

nobu	2014-10-16 17:15:46 +0900 (Thu, 16 Oct 2014)

  New Revision: 47977

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47977

  Log:
    signal.c: abort if nesting reserved signal
    
    * signal.c (check_reserved_signal): abort if reserved signal
      received in reserved signal handlers.

  Modified files:
    trunk/signal.c
Index: signal.c
===================================================================
--- signal.c	(revision 47976)
+++ signal.c	(revision 47977)
@@ -799,10 +799,14 @@ check_stack_overflow(const void *addr) https://github.com/ruby/ruby/blob/trunk/signal.c#L799
 #define MESSAGE_FAULT_ADDRESS
 #endif
 
+#if defined SIGSEGV || defined SIGBUS || defined SIGILL || defined SIGFPE
+static void check_reserved_signal(const char *name);
+
 #ifdef SIGBUS
 static RETSIGTYPE
 sigbus(int sig SIGINFO_ARG)
 {
+    check_reserved_signal("BUS");
 /*
  * Mac OS X makes KERN_PROTECTION_FAILURE when thread touch guard page.
  * and it's delivered as SIGBUS instead of SIGSEGV to userland. It's crazy
@@ -815,7 +819,6 @@ sigbus(int sig SIGINFO_ARG) https://github.com/ruby/ruby/blob/trunk/signal.c#L819
 }
 #endif
 
-#ifdef SIGSEGV
 static void
 ruby_abort(void)
 {
@@ -830,25 +833,49 @@ ruby_abort(void) https://github.com/ruby/ruby/blob/trunk/signal.c#L833
 
 }
 
-static int segv_received = 0;
 extern int ruby_disable_gc;
 
+#ifdef SIGSEGV
 static RETSIGTYPE
 sigsegv(int sig SIGINFO_ARG)
 {
-    if (segv_received) {
+    check_reserved_signal("SEGV");
+    CHECK_STACK_OVERFLOW();
+    rb_bug_context(SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
+}
+#endif
+
+#ifdef SIGILL
+static RETSIGTYPE
+sigill(int sig SIGINFO_ARG)
+{
+    check_reserved_signal("ILL");
+#if defined __APPLE__
+    CHECK_STACK_OVERFLOW();
+#endif
+    rb_bug_context(SIGINFO_CTX, "Illegal instruction" MESSAGE_FAULT_ADDRESS);
+}
+#endif
+
+static void
+check_reserved_signal(const char *name)
+{
+    static const char *received;
+    const char *prev = ATOMIC_PTR_EXCHANGE(received, name);
+
+    if (prev) {
 	ssize_t RB_UNUSED_VAR(err);
-	static const char msg[] = "SEGV received in SEGV handler\n";
+	static const char msg1[] = " received in ";
+	static const char msg2[] = " handler\n";
 
-	err = write(2, msg, sizeof(msg));
+	err = write(2, name, strlen(name));
+	err = write(2, msg1, sizeof(msg1));
+	err = write(2, prev, strlen(prev));
+	err = write(2, msg2, sizeof(msg2));
 	ruby_abort();
     }
 
-    CHECK_STACK_OVERFLOW();
-
-    segv_received = 1;
     ruby_disable_gc = 1;
-    rb_bug_context(SIGINFO_CTX, "Segmentation fault" MESSAGE_FAULT_ADDRESS);
 }
 #endif
 
@@ -1381,6 +1408,9 @@ Init_signal(void) https://github.com/ruby/ruby/blob/trunk/signal.c#L1408
 #ifdef SIGBUS
 	install_sighandler(SIGBUS, (sighandler_t)sigbus);
 #endif
+#ifdef SIGILL
+	install_sighandler(SIGILL, (sighandler_t)sigill);
+#endif
 #ifdef SIGSEGV
 # ifdef USE_SIGALTSTACK
 	rb_register_sigaltstack(GET_THREAD());

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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