summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-02 03:58:47 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-04-02 03:58:47 +0000
commit3108dc4b38c05264e7ce3b117b6c00894b76b9fc (patch)
treeb580cd73df1ac8cb17a8073df910a5eaa2aed2d0 /signal.c
parent9c215874b929cc62ebb0a41eb1993d37d6abcb73 (diff)
merge revision(s) 39354,39356,39382: [Backport #5014]
* signal.c (sigsegv): avoid to use async signal unsafe functions when nested sigsegv is happen. [Bug #5014] [ruby-dev:44082] * signal.c (check_stack_overflow): extract duplicated code and get rid of declaration-after-statement. [Bug #5014] * signal.c (ruby_abort): fix typo in r39354 [Bug #5014] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@40050 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/signal.c b/signal.c
index b4e64d09f8..de0413049a 100644
--- a/signal.c
+++ b/signal.c
@@ -564,6 +564,23 @@ rb_get_next_signal(void)
return sig;
}
+
+#ifdef USE_SIGALTSTACK
+static void
+check_stack_overflow(const void *addr)
+{
+ 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, addr)) {
+ ruby_thread_stack_overflow(th);
+ }
+}
+#define CHECK_STACK_OVERFLOW() check_stack_overflow(info->si_addr)
+#else
+#define CHECK_STACK_OVERFLOW() (void)0
+#endif
+
#ifdef SIGBUS
static RETSIGTYPE
sigbus(int sig SIGINFO_ARG)
@@ -573,41 +590,44 @@ sigbus(int sig SIGINFO_ARG)
* 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);
- }
+#if defined __APPLE__
+ CHECK_STACK_OVERFLOW();
#endif
rb_bug("Bus Error");
}
#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)
{
-#ifdef 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
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");
+ char msg[] = "SEGV received in SEGV handler\n";
+ write(2, msg, sizeof(msg));
+ ruby_abort();
}
+
+ CHECK_STACK_OVERFLOW();
+
+ segv_received = 1;
+ ruby_disable_gc_stress = 1;
+ rb_bug("Segmentation fault");
}
#endif