aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--defs/id.def2
-rw-r--r--eval.c23
-rw-r--r--test/ruby/test_exception.rb6
-rw-r--r--vm_insnhelper.c12
5 files changed, 32 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c85cb6297..248742cfe3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/eval.c b/eval.c
index ee47a44da4..ad7f1a5b75 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);
}
}
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 *