ruby-changes:31628
From: nobu <ko1@a...>
Date: Mon, 18 Nov 2013 22:48:03 +0900 (JST)
Subject: [ruby-changes:31628] nobu:r43707 (trunk): eval_intern.h: refine stack overflow detection
nobu 2013-11-18 22:47:56 +0900 (Mon, 18 Nov 2013) New Revision: 43707 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43707 Log: eval_intern.h: refine stack overflow detection * 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(). Modified files: trunk/ChangeLog trunk/eval_intern.h trunk/test/ruby/test_exception.rb trunk/vm_eval.c Index: eval_intern.h =================================================================== --- eval_intern.h (revision 43706) +++ eval_intern.h (revision 43707) @@ -95,8 +95,7 @@ extern int select_large_fdset(int, fd_se https://github.com/ruby/ruby/blob/trunk/eval_intern.h#L95 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, i https://github.com/ruby/ruby/blob/trunk/eval_intern.h#L128 [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() Index: ChangeLog =================================================================== --- ChangeLog (revision 43706) +++ ChangeLog (revision 43707) @@ -1,4 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Mon Nov 18 22:47:11 2013 Nobuyoshi Nakada <nobu@r...> +Mon Nov 18 22:47:54 2013 Nobuyoshi Nakada <nobu@r...> + + * 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. Index: vm_eval.c =================================================================== --- vm_eval.c (revision 43706) +++ vm_eval.c (revision 43707) @@ -1823,7 +1823,7 @@ rb_catch_obj(VALUE t, VALUE (*func)(), V https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1823 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 */ Index: test/ruby/test_exception.rb =================================================================== --- test/ruby/test_exception.rb (revision 43706) +++ test/ruby/test_exception.rb (revision 43707) @@ -477,6 +477,14 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L477 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/