diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | defs/id.def | 2 | ||||
-rw-r--r-- | eval.c | 23 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 6 | ||||
-rw-r--r-- | vm_insnhelper.c | 12 |
5 files changed, 32 insertions, 18 deletions
@@ -1,3 +1,10 @@ +Sat Jun 28 13:58:19 2014 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * 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. + Sat Jun 28 04:08:22 2014 NARUSE, Yui <naruse@ruby-lang.org> * lib/uri/mailto.rb: update to latest specs, RFC 6068 and HTML5. diff --git a/defs/id.def b/defs/id.def index 42386e5f36..f7fffbde3c 100644 --- a/defs/id.def +++ b/defs/id.def @@ -36,6 +36,8 @@ firstline, predefined = __LINE__+1, %[\ to_a to_s to_i + bt + bt_locations _ UScore "/*NULL*/" NULL @@ -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); } } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index c71c7dfc64..48d470f8ed 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -529,8 +529,10 @@ end.join end def test_stackoverflow - e = assert_raise(SystemStackError){m} - assert_operator(e.backtrace.size, :>, 10) + feature6216 = '[ruby-core:43794] [Feature #6216]' + e = assert_raise(SystemStackError, feature6216) {m} + level = e.backtrace.size + assert_operator(level, :>, 10, feature6216) end def test_machine_stackoverflow diff --git a/vm_insnhelper.c b/vm_insnhelper.c index e9dc27139a..8cd9295d66 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -24,12 +24,18 @@ static rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp); -static void -vm_stackoverflow(void) +VALUE +ruby_vm_sysstack_error_copy(void) { VALUE e = rb_obj_alloc(rb_eSysStackError); rb_obj_copy_ivar(e, sysstack_error); - rb_exc_raise(e); + return e; +} + +static void +vm_stackoverflow(void) +{ + rb_exc_raise(ruby_vm_sysstack_error_copy()); } static inline rb_control_frame_t * |