summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-28 04:58:25 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-06-28 04:58:25 +0000
commit3ff85b795ac42976e5ed51c6add0b18660455abd (patch)
tree89fb30ecffde7408e7a2e1a76cb1c8a182a77fc6 /eval.c
parent76bb597728c0d9a2228367e0ecaf6b92b7ffdfd7 (diff)
eval.c: no method calls at stack overflow
* eval.c (setup_exception): get rid of method calls before raising stack overflow, not to cause stack overflow again. * defs/id.def: add IDs for backtraces. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46593 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/eval.c b/eval.c
index ee47a44..ad7f1a5 100644
--- a/eval.c
+++ b/eval.c
@@ -469,7 +469,6 @@ sysstack_error_p(VALUE exc)
static void
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
{
- VALUE at;
VALUE e;
const char *file = 0;
volatile int line = 0;
@@ -492,24 +491,22 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
file = rb_sourcefile();
if (file) line = rb_sourceline();
if (file && !NIL_P(mesg)) {
- if (mesg == sysstack_error) {
- /* machine stack overflow, reduce too long backtrace */
- ID func = rb_frame_this_func();
- at = rb_enc_sprintf(rb_usascii_encoding(), "%s:%d", file, line);
- if (func) {
- VALUE name = rb_id2str(func);
- if (name) rb_str_catf(at, ":in `%"PRIsVALUE"'", name);
+ VALUE at;
+ if (sysstack_error_p(mesg)) {
+ at = rb_vm_backtrace_object();
+ if (mesg == sysstack_error) {
+ VALUE ruby_vm_sysstack_error_copy(void);
+ mesg = ruby_vm_sysstack_error_copy();
}
- at = rb_ary_new3(1, at);
- mesg = rb_obj_dup(mesg);
- rb_iv_set(mesg, "bt", at);
+ rb_ivar_set(mesg, idBt, at);
+ rb_ivar_set(mesg, idBt_locations, at);
}
- else if (sysstack_error_p(mesg) || NIL_P(at = get_backtrace(mesg))) {
+ else if (NIL_P(get_backtrace(mesg))) {
at = rb_vm_backtrace_object();
if (OBJ_FROZEN(mesg)) {
mesg = rb_obj_dup(mesg);
}
- rb_iv_set(mesg, "bt_locations", at);
+ rb_ivar_set(mesg, idBt_locations, at);
set_backtrace(mesg, at);
}
}