summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-23 02:35:18 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-23 02:35:18 (GMT)
commit053759edfc80a51eeea0cfa9c46e4bb57589bf00 (patch)
tree9a03d850a4823e5e50269ec5aaa721102938e404 /eval.c
parentcf3890205fc657119a5dd7d94955122b0cfa00f2 (diff)
Backtrace for SystemStackError
* eval.c (setup_exception): set backtrace in system stack error other than the pre-allocated sysstack_error. [Feature #6216] * proc.c (Init_Proc): freeze the pre-allocated sysstack_error. * vm_insnhelper.c (vm_stackoverflow): raise new instance for each times without calling any methods to keep the backtrace with no further stack overflow. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46502 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/eval.c b/eval.c
index afad73c..4dada48 100644
--- a/eval.c
+++ b/eval.c
@@ -460,6 +460,12 @@ exc_setup_cause(VALUE exc, VALUE cause)
return exc;
}
+static inline int
+sysstack_error_p(VALUE exc)
+{
+ return exc == sysstack_error || (!SPECIAL_CONST_P(exc) && RBASIC_CLASS(exc) == rb_eSysStackError);
+}
+
static void
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
{
@@ -497,8 +503,7 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
rb_iv_set(mesg, "bt", at);
}
else {
- at = get_backtrace(mesg);
- if (NIL_P(at)) {
+ if (sysstack_error_p(mesg) || NIL_P(at = get_backtrace(mesg))) {
at = rb_vm_backtrace_object();
if (OBJ_FROZEN(mesg)) {
mesg = rb_obj_dup(mesg);
@@ -697,7 +702,7 @@ make_exception(int argc, const VALUE *argv, int isstr)
exc = argv[0];
n = 1;
exception_call:
- if (exc == sysstack_error) return exc;
+ if (sysstack_error_p(exc)) return exc;
CONST_ID(exception, "exception");
mesg = rb_check_funcall(exc, exception, n, argv+1);
if (mesg == Qundef) {