summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-09 12:33:26 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-03-09 12:33:26 +0000
commit9913bbba6bea268d6e9ea77b2d5c55956930eeb9 (patch)
tree4585362f5fb5e08ce87dfaa4bf9ffecd8667252b /signal.c
parent54281916e9623b132b6745bdc9ee9a397eff7398 (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_2_0_0@39654 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 c823347899..4fe942bf30 100644
--- a/signal.c
+++ b/signal.c
@@ -604,6 +604,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)
@@ -613,41 +630,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 __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