summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--eval_intern.h5
-rw-r--r--test/ruby/test_exception.rb8
-rw-r--r--vm_eval.c2
4 files changed, 20 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 761af2d102..d4c5a2925b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
-Mon Nov 18 22:47:11 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+Mon Nov 18 22:47:54 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval_intern.h (TH_PUSH_TAG, TH_EXEC_TAG): refine stack overflow
+ detection. chain local tag after setjmp() successed on it, because
+ calling setjmp() also can overflow the stack.
+ [ruby-dev:47804] [Bug #9109]
+
+ * vm_eval.c (rb_catch_obj): now th->tag points previous tag until
+ TH_EXEC_TAG().
* thread_pthread.c (ruby_init_stack): set stack_start properly by
get_main_stack() if possible.
diff --git a/eval_intern.h b/eval_intern.h
index cf7fb23197..e32eafe2a8 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -95,8 +95,7 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval
rb_thread_t * const _th = (th); \
struct rb_vm_tag _tag; \
_tag.tag = 0; \
- _tag.prev = _th->tag; \
- _th->tag = &_tag;
+ _tag.prev = _th->tag;
#define TH_POP_TAG() \
_th->tag = _tag.prev; \
@@ -129,7 +128,7 @@ rb_threadptr_tag_jump(rb_thread_t *th, int st)
[ISO/IEC 9899:1999] 7.13.1.1
*/
#define TH_EXEC_TAG() \
- (ruby_setjmp(_th->tag->buf) ? rb_threadptr_tag_state(_th) : 0)
+ (ruby_setjmp(_tag.buf) ? rb_threadptr_tag_state(_th) : (_th->tag = &_tag, 0))
#define EXEC_TAG() \
TH_EXEC_TAG()
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 92438ad742..ca6e43ee13 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -477,6 +477,14 @@ end.join
assert_raise(SystemStackError){m}
end
+ def test_machine_stackoverflow
+ bug9109 = '[ruby-dev:47804] [Bug #9109]'
+ assert_separately([], <<-SRC)
+ h = {a: ->{h[:a].call}}
+ assert_raise(SystemStackError, #{bug9109.dump}) {h[:a].call}
+ SRC
+ end
+
def test_cause
msg = "[Feature #8257]"
cause = nil
diff --git a/vm_eval.c b/vm_eval.c
index bace6bbbcf..24bac12bbf 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1823,7 +1823,7 @@ rb_catch_obj(VALUE t, VALUE (*func)(), VALUE data)
TH_PUSH_TAG(th);
- th->tag->tag = tag;
+ _tag.tag = tag;
if ((state = TH_EXEC_TAG()) == 0) {
/* call with argc=1, argv = [tag], block = Qnil to insure compatibility */