From 7355c6d9c99d7636c9acbd262149f72d1f900d9f Mon Sep 17 00:00:00 2001 From: kosaki Date: Thu, 21 Feb 2013 05:18:38 +0000 Subject: [PATCH] * signal.c (sigsegv): avoid to use async signal unsafe functions when nested sigsegv is happen. [Bug #5014] [ruby-dev:44082] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ signal.c | 35 +++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69534f618a..5741667979 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Feb 21 14:14:13 2013 KOSAKI Motohiro + + * signal.c (sigsegv): avoid to use async signal unsafe functions + when nested sigsegv is happen. + [Bug #5014] [ruby-dev:44082] + Thu Feb 21 13:47:59 2013 KOSAKI Motohiro * file.c (rb_group_member): added an error check. SUS says, diff --git a/signal.c b/signal.c index c823347899..4bcb79e389 100644 --- a/signal.c +++ b/signal.c @@ -626,10 +626,31 @@ sigbus(int sig SIGINFO_ARG) #endif #ifdef SIGSEGV +static void ruby_abort(void) +{ +#ifdef __sun + /* Solaris's abort() is async signal unsafe. Of course, it is not + * POSIX compliant. + */ + raise(SIGABRT) +#else + abort(); +#endif + +} + static int segv_received = 0; +extern int ruby_disable_gc_stress; + static RETSIGTYPE sigsegv(int sig SIGINFO_ARG) { + if (segv_received) { + char msg[] = "SEGV received in SEGV handler\n"; + write(2, msg, sizeof(msg)); + ruby_abort(); + } + #ifdef USE_SIGALTSTACK int ruby_stack_overflowed_p(const rb_thread_t *, const void *); NORETURN(void ruby_thread_stack_overflow(rb_thread_t *th)); @@ -638,16 +659,10 @@ sigsegv(int sig SIGINFO_ARG) ruby_thread_stack_overflow(th); } #endif - if (segv_received) { - fprintf(stderr, "SEGV received in SEGV handler\n"); - abort(); - } - else { - extern int ruby_disable_gc_stress; - segv_received = 1; - ruby_disable_gc_stress = 1; - rb_bug("Segmentation fault"); - } + + segv_received = 1; + ruby_disable_gc_stress = 1; + rb_bug("Segmentation fault"); } #endif