diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-21 05:18:38 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-02-21 05:18:38 +0000 |
commit | 7355c6d9c99d7636c9acbd262149f72d1f900d9f (patch) | |
tree | 4532789c68a73f9130f7f0cbd404a0273a5bbfce | |
parent | 8a9dc061f5737543eaca17ceafa6ebe4886cb26e (diff) | |
download | ruby-7355c6d9c99d7636c9acbd262149f72d1f900d9f.tar.gz |
* 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
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | signal.c | 35 |
2 files changed, 31 insertions, 10 deletions
@@ -1,3 +1,9 @@ +Thu Feb 21 14:14:13 2013 KOSAKI Motohiro <kosaki.motohiro@gmail.com> + + * 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 <kosaki.motohiro@gmail.com> * file.c (rb_group_member): added an error check. SUS says, @@ -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 |