e$B$J$+$@$G$9!#e(B
At Mon, 2 Nov 2009 11:52:04 +0900,
Yukihiro M. wrote in [ruby-dev:39601]:
|e$B$^$Ge(Bsweepe$B$7$h$&$H$7$FMn$A$F$$$k46$8$G$9!#e(B
scan?
e$B$G$7$?!#e(BGCe$B$O>$7$/$J$$$b$N$G!#e(B
e$B$N$$$:$l$+$,I,MW$H$$$&$3$H$G$9$+!#e(B
e$BA0<T$N$[$&$,$$$$$s$8$c$J$$$G$7$g$&$+!#BeBX%9%?%C%/;HMQCf$Ne(BGCe$B$G%9e(B
e$B%?%C%/%*!<%P%U%m!<$7$?$j$H$+9M$($k$H!#e(B
e$B$=$l$h$j$b$`$7$me(Brb_longjmp e$B$G$Ne(Bbacktracee$B$N3d$jEv$F$re(Blazye$B$K$9e(B
e$B$Y$-$J$N$+$J$"!#$G$b!"%P%C%/$H%l!<%9>pJs$r5-O?$9$k>l=j$O$$$:e(B
e$B$l$K$;$hI,MW$J$o$1$@$7e(B…e$B!#e(B
e$B!V%P%C%/%H%l!<%9>pJs$r5-O?$9$k>l=j!W$H$$$&$N$Oe(B?
e$B$H$j$"$($:e(BJUMP_TAGe$B$N$H$-$K%A%’%C%/$5$;$k$h$&$K$7$F$_$^$7$?!#e(B
Index: eval_error.c
— eval_error.c (revision 25629)
+++ eval_error.c (working copy)
@@ -273,2 +273,14 @@ error_handle(int ex)
return status;
}
+
+void
+ruby_threadptr_handle_critical_exception(rb_thread_t *th)
+{
- VALUE e = th->errinfo, bt;
- if (!OBJ_FROZEN(e)) return;
- if (ruby_threadptr_stack_check(th)) return;
- bt = rb_threadptr_backtrace(th, -1);
- th->errinfo = e = rb_obj_dup(e);
- set_backtrace(e, bt);
- rb_thread_raised_reset(th, RAISED_STACKOVERFLOW|RAISED_NOMEMORY);
+}
Index: eval_intern.h
===================================================================
— eval_intern.h (revision 25629)
+++ eval_intern.h (working copy)
@@ -131,5 +131,7 @@ NORETURN(void _longjmp(jmp_buf, int));
#define TH_JUMP_TAG(th, st) do { \
- ruby_longjmp(th->tag->buf,(st)); \
- if (rb_thread_raised_p(th, RAISED_STACKOVERFLOW|RAISED_NOMEMORY)) \
- ruby_threadptr_handle_critical_exception(th); \
- ruby_longjmp(th->tag->buf,(st));
} while (0)
@@ -192,4 +194,6 @@ int rb_threadptr_reset_raised(rb_thread_
#define rb_thread_raised_p(th, f) (((th)->raised_flag & (f)) != 0)
#define rb_thread_raised_clear(th) ((th)->raised_flag = 0)
+void ruby_threadptr_handle_critical_exception(rb_thread_t *th);
+int ruby_threadptr_stack_check(rb_thread_t *th);
VALUE rb_f_eval(int argc, VALUE *argv, VALUE self);
Index: gc.c
— gc.c (revision 25629)
+++ gc.c (working copy)
@@ -1205,9 +1205,8 @@ ruby_stack_length(VALUE **p)
}
-static int
-stack_check(void)
+int
+ruby_threadptr_stack_check(rb_thread_t *th)
{
int ret;
- rb_thread_t *th = GET_THREAD();
SET_STACK_END;
ret = STACK_LENGTH > STACK_LEVEL_MAX - GC_WATER_MARK;
@@ -1221,4 +1220,10 @@ stack_check(void)
}
+static inline int
+stack_check(void)
+{
- return ruby_threadptr_stack_check(GET_THREAD());
+}
-
int
ruby_stack_check(void)
Index: signal.c
— signal.c (revision 25629)
+++ signal.c (working copy)
@@ -599,6 +599,4 @@ 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)) {
Index: thread.c
===================================================================
— thread.c (revision 25629)
+++ thread.c (working copy)
@@ -1347,12 +1347,7 @@ void
ruby_thread_stack_overflow(rb_thread_t *th)
{
- th->raised_flag = 0;
-#ifdef USE_SIGALTSTACK
- th->raised_flag = 0;
- rb_exc_raise(sysstack_error);
-#else
- th->raised_flag = RAISED_STACKOVERFLOW;
th->errinfo = sysstack_error;
- TH_JUMP_TAG(th, TAG_RAISE);
-#endif
- ruby_longjmp(th->tag->buf, TAG_RAISE);
}
Index: vm_core.h
— vm_core.h (revision 25629)
+++ vm_core.h (working copy)
@@ -616,6 +616,8 @@ void *rb_thread_call_with_gvl(void *(*fu
int ruby_thread_has_gvl_p(void);
VALUE rb_make_backtrace(void);
+VALUE rb_threadptr_backtrace(rb_thread_t *th, int lev);
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
int rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg);
+int rb_threadptr_backtrace_each(rb_thread_t *th, int lev,
rb_backtrace_iter_func *iter, void *arg);
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th,
rb_control_frame_t *cfp);
VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE
method);
@@ -654,4 +656,6 @@ void rb_threadptr_signal_raise(rb_thread
void rb_threadptr_signal_exit(rb_thread_t *th);
void rb_threadptr_execute_interrupts(rb_thread_t *);
+int ruby_stack_overflowed_p(const rb_thread_t *, const void *);
+void ruby_thread_stack_overflow(rb_thread_t *th);
#define RUBY_VM_CHECK_INTS_TH(th) do {
Index: vm_eval.c
— vm_eval.c (revision 25629)
+++ vm_eval.c (working copy)
@@ -192,11 +192,8 @@ rb_call_super(int argc, const VALUE *arg
static inline void
-stack_check(void)
+stack_check(rb_thread_t *th)
{
- rb_thread_t *th = GET_THREAD();
- if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW) &&
ruby_stack_check()) {
- rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
- rb_exc_raise(sysstack_error);
- ruby_thread_stack_overflow(th);
}
}
@@ -231,5 +228,5 @@ rb_call0(VALUE recv, ID mid, int argc, c
return method_missing(recv, mid, argc, argv, call_status);
}
- stack_check(th);
return vm_call0(th, recv, mid, argc, argv, me);
}
@@ -286,5 +283,5 @@ check_funcall(VALUE recv, ID mid, int ar
}
}
- stack_check(th);
return vm_call0(th, recv, mid, argc, argv, me);
}
@@ -434,5 +431,5 @@ raise_method_missing(rb_thread_t *th, in
}
int
+rb_threadptr_backtrace_each(rb_thread_t *th, int lev,
rb_backtrace_iter_func *iter, void *arg)
+{
- return vm_backtrace_each(th, lev, iter, arg);
+}
-
+VALUE
+rb_threadptr_backtrace(rb_thread_t *th, int lev)
+{
- return vm_backtrace(th, lev);
+}
-
+int
rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg)
{