[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]