summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--eval.c14
-rw-r--r--test/ruby/test_exception.rb4
3 files changed, 16 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 248742c..0ca27b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,7 @@
-Sat Jun 28 13:58:19 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Sat Jun 28 13:58:48 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval.c (setup_exception): should not overwrite SystemStackError
+ backtrace if set already. [ruby-core:63377] [Feature #6216]
* eval.c (setup_exception): get rid of method calls before raising
stack overflow, not to cause stack overflow again.
diff --git a/eval.c b/eval.c
index ad7f1a5..fbe17d0 100644
--- a/eval.c
+++ b/eval.c
@@ -493,13 +493,15 @@ setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
if (file && !NIL_P(mesg)) {
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();
+ if (NIL_P(rb_attr_get(mesg, idBt))) {
+ at = rb_vm_backtrace_object();
+ if (mesg == sysstack_error) {
+ VALUE ruby_vm_sysstack_error_copy(void);
+ mesg = ruby_vm_sysstack_error_copy();
+ }
+ rb_ivar_set(mesg, idBt, at);
+ rb_ivar_set(mesg, idBt_locations, at);
}
- rb_ivar_set(mesg, idBt, at);
- rb_ivar_set(mesg, idBt_locations, at);
}
else if (NIL_P(get_backtrace(mesg))) {
at = rb_vm_backtrace_object();
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 48d470f..919220e 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -533,6 +533,10 @@ end.join
e = assert_raise(SystemStackError, feature6216) {m}
level = e.backtrace.size
assert_operator(level, :>, 10, feature6216)
+
+ feature6216 = '[ruby-core:63377] [Feature #6216]'
+ e = assert_raise(SystemStackError, feature6216) {raise e}
+ assert_equal(level, e.backtrace.size, feature6216)
end
def test_machine_stackoverflow