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

ruby-changes:34421

From: nobu <ko1@a...>
Date: Mon, 23 Jun 2014 11:35:24 +0900 (JST)
Subject: [ruby-changes:34421] nobu:r46502 (trunk): Backtrace for SystemStackError

nobu	2014-06-23 11:35:18 +0900 (Mon, 23 Jun 2014)

  New Revision: 46502

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=46502

  Log:
    Backtrace for SystemStackError
    
    * eval.c (setup_exception): set backtrace in system stack error
      other than the pre-allocated sysstack_error.  [Feature #6216]
    * proc.c (Init_Proc): freeze the pre-allocated sysstack_error.
    * vm_insnhelper.c (vm_stackoverflow): raise new instance for each
      times without calling any methods to keep the backtrace with no
      further stack overflow.

  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/proc.c
    trunk/test/ruby/test_exception.rb
    trunk/vm_insnhelper.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 46501)
+++ ChangeLog	(revision 46502)
@@ -1,4 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
-Mon Jun 23 11:32:59 2014  Nobuyoshi Nakada  <nobu@r...>
+Mon Jun 23 11:35:01 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* eval.c (setup_exception): set backtrace in system stack error
+	  other than the pre-allocated sysstack_error.  [Feature #6216]
+
+	* proc.c (Init_Proc): freeze the pre-allocated sysstack_error.
+
+	* vm_insnhelper.c (vm_stackoverflow): raise new instance for each
+	  times without calling any methods to keep the backtrace with no
+	  further stack overflow.
 
 	* object.c (rb_obj_copy_ivar): extract function to copy instance
 	  variables only for T_OBJECT from init_copy.
Index: proc.c
===================================================================
--- proc.c	(revision 46501)
+++ proc.c	(revision 46502)
@@ -2748,6 +2748,7 @@ Init_Proc(void) https://github.com/ruby/ruby/blob/trunk/proc.c#L2748
     sysstack_error = rb_exc_new3(rb_eSysStackError,
 				 rb_obj_freeze(rb_str_new2("stack level too deep")));
     OBJ_TAINT(sysstack_error);
+    OBJ_FREEZE(sysstack_error);
 
     /* utility functions */
     rb_define_global_function("proc", rb_block_proc, 0);
Index: eval.c
===================================================================
--- eval.c	(revision 46501)
+++ eval.c	(revision 46502)
@@ -460,6 +460,12 @@ exc_setup_cause(VALUE exc, VALUE cause) https://github.com/ruby/ruby/blob/trunk/eval.c#L460
     return exc;
 }
 
+static inline int
+sysstack_error_p(VALUE exc)
+{
+    return exc == sysstack_error || (!SPECIAL_CONST_P(exc) && RBASIC_CLASS(exc) == rb_eSysStackError);
+}
+
 static void
 setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg, VALUE cause)
 {
@@ -497,8 +503,7 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L503
 	    rb_iv_set(mesg, "bt", at);
 	}
 	else {
-	    at = get_backtrace(mesg);
-	    if (NIL_P(at)) {
+	    if (sysstack_error_p(mesg) || NIL_P(at = get_backtrace(mesg))) {
 		at = rb_vm_backtrace_object();
 		if (OBJ_FROZEN(mesg)) {
 		    mesg = rb_obj_dup(mesg);
@@ -697,7 +702,7 @@ make_exception(int argc, const VALUE *ar https://github.com/ruby/ruby/blob/trunk/eval.c#L702
 	exc = argv[0];
 	n = 1;
       exception_call:
-	if (exc == sysstack_error) return exc;
+	if (sysstack_error_p(exc)) return exc;
 	CONST_ID(exception, "exception");
 	mesg = rb_check_funcall(exc, exception, n, argv+1);
 	if (mesg == Qundef) {
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 46501)
+++ vm_insnhelper.c	(revision 46502)
@@ -27,7 +27,9 @@ static rb_control_frame_t *vm_get_ruby_l https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L27
 static void
 vm_stackoverflow(void)
 {
-    rb_exc_raise(sysstack_error);
+    VALUE e = rb_obj_alloc(rb_eSysStackError);
+    rb_obj_copy_ivar(e, sysstack_error);
+    rb_exc_raise(e);
 }
 
 static inline rb_control_frame_t *
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 46501)
+++ test/ruby/test_exception.rb	(revision 46502)
@@ -529,7 +529,8 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L529
   end
 
   def test_stackoverflow
-    assert_raise(SystemStackError){m}
+    e = assert_raise(SystemStackError){m}
+    assert_operator(e.backtrace.size, :>, 10)
   end
 
   def test_machine_stackoverflow

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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