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

ruby-changes:44694

From: nobu <ko1@a...>
Date: Sun, 13 Nov 2016 14:25:59 +0900 (JST)
Subject: [ruby-changes:44694] nobu:r56767 (trunk): error.c: redefined backtrace

nobu	2016-11-13 14:25:54 +0900 (Sun, 13 Nov 2016)

  New Revision: 56767

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

  Log:
    error.c: redefined backtrace
    
    * error.c (rb_get_backtrace): honor redefined Exception#backtrace
      method.  [ruby-core:78097] [Bug #12925]
    
    * eval.c (setup_exception): rescue exceptions during backtrace
      setup.

  Modified files:
    trunk/error.c
    trunk/eval.c
    trunk/test/ruby/test_exception.rb
Index: eval.c
===================================================================
--- eval.c	(revision 56766)
+++ eval.c	(revision 56767)
@@ -507,13 +507,25 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L507
 		rb_ivar_set(mesg, idBt_locations, at);
 	    }
 	}
-	else if (NIL_P(rb_get_backtrace(mesg))) {
-	    at = rb_vm_backtrace_object();
-	    if (OBJ_FROZEN(mesg)) {
-		mesg = rb_obj_dup(mesg);
+	else {
+	    int status;
+
+	    TH_PUSH_TAG(th);
+	    if ((status = EXEC_TAG()) == 0) {
+		VALUE bt;
+		if (rb_threadptr_set_raised(th)) goto fatal;
+		bt = rb_get_backtrace(mesg);
+		if (NIL_P(bt)) {
+		    at = rb_vm_backtrace_object();
+		    if (OBJ_FROZEN(mesg)) {
+			mesg = rb_obj_dup(mesg);
+		    }
+		    rb_ivar_set(mesg, idBt_locations, at);
+		    set_backtrace(mesg, at);
+		}
+		rb_threadptr_reset_raised(th);
 	    }
-	    rb_ivar_set(mesg, idBt_locations, at);
-	    set_backtrace(mesg, at);
+	    TH_POP_TAG();
 	}
     }
 
@@ -556,6 +568,7 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L568
     }
 
     if (rb_threadptr_set_raised(th)) {
+      fatal:
 	th->errinfo = exception_error;
 	rb_threadptr_reset_raised(th);
 	TH_JUMP_TAG(th, TAG_FATAL);
Index: error.c
===================================================================
--- error.c	(revision 56766)
+++ error.c	(revision 56767)
@@ -885,17 +885,20 @@ exc_backtrace(VALUE exc) https://github.com/ruby/ruby/blob/trunk/error.c#L885
 VALUE
 rb_get_backtrace(VALUE exc)
 {
-    VALUE info, klass = rb_eException;
     ID mid = id_backtrace;
-    rb_thread_t *th = GET_THREAD();
-    if (NIL_P(exc))
-	return Qnil;
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
-    info = exc_backtrace(exc);
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
-    if (NIL_P(info))
-	return Qnil;
-    return rb_check_backtrace(info);
+    if (rb_method_basic_definition_p(CLASS_OF(exc), id_backtrace)) {
+	VALUE info, klass = rb_eException;
+	rb_thread_t *th = GET_THREAD();
+	if (NIL_P(exc))
+	    return Qnil;
+	EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, exc, mid, mid, klass, Qundef);
+	info = exc_backtrace(exc);
+	EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, exc, mid, mid, klass, info);
+	if (NIL_P(info))
+	    return Qnil;
+	return rb_check_backtrace(info);
+    }
+    return rb_funcall(exc, mid, 0, 0);
 }
 
 /*
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 56766)
+++ test/ruby/test_exception.rb	(revision 56767)
@@ -965,4 +965,38 @@ $stderr = $stdout; raise "\x82\xa0"') do https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L965
       }
     end;
   end
+
+  def test_redefined_backtrace
+    assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+    begin;
+      $exc = nil
+
+      class Exception
+        undef backtrace
+        def backtrace
+          $exc = self
+        end
+      end
+
+      e = assert_raise(RuntimeError) {
+        raise RuntimeError, "hello"
+      }
+      assert_same(e, $exc)
+    end;
+  end
+
+  def test_wrong_backtrace
+    assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+    begin;
+      class Exception
+        undef backtrace
+        def backtrace(a)
+        end
+      end
+
+      assert_raise(RuntimeError) {
+        raise RuntimeError, "hello"
+      }
+    end;
+  end
 end

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

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