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/