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

ruby-changes:66873

From: Nobuyoshi <ko1@a...>
Date: Fri, 23 Jul 2021 12:01:35 +0900 (JST)
Subject: [ruby-changes:66873] fc4dd45d01 (master): Show exception in finalizer [Feature #17798]

https://git.ruby-lang.org/ruby.git/commit/?id=fc4dd45d01

From fc4dd45d0142221880d1b2c9b54dee0597be2b78 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Fri, 23 Jul 2021 00:32:09 +0900
Subject: Show exception in finalizer [Feature #17798]

---
 gc.c                          | 15 ++++++++++++++-
 test/ruby/test_objectspace.rb |  7 +++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gc.c b/gc.c
index 97a4c8b..61ff6ab 100644
--- a/gc.c
+++ b/gc.c
@@ -3988,6 +3988,16 @@ run_single_final(VALUE cmd, VALUE objid) https://github.com/ruby/ruby/blob/trunk/gc.c#L3988
 }
 
 static void
+warn_exception_in_finalizer(rb_execution_context_t *ec, VALUE final)
+{
+    if (final != Qundef) {
+	VALUE errinfo = ec->errinfo;
+	rb_warn("Exception in finalizer %+"PRIsVALUE, final);
+	rb_ec_error_print(ec, errinfo);
+    }
+}
+
+static void
 run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
 {
     long i;
@@ -3995,6 +4005,7 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table) https://github.com/ruby/ruby/blob/trunk/gc.c#L4005
     volatile struct {
 	VALUE errinfo;
 	VALUE objid;
+	VALUE final;
 	rb_control_frame_t *cfp;
 	long finished;
     } saved;
@@ -4007,16 +4018,18 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table) https://github.com/ruby/ruby/blob/trunk/gc.c#L4018
     saved.objid = rb_obj_id(obj);
     saved.cfp = ec->cfp;
     saved.finished = 0;
+    saved.final = Qundef;
 
     EC_PUSH_TAG(ec);
     state = EC_EXEC_TAG();
     if (state != TAG_NONE) {
 	++saved.finished;	/* skip failed finalizer */
+	warn_exception_in_finalizer(ec, ATOMIC_VALUE_EXCHANGE(saved.final, Qundef));
     }
     for (i = saved.finished;
 	 RESTORE_FINALIZER(), i<RARRAY_LEN(table);
 	 saved.finished = ++i) {
-	run_single_final(RARRAY_AREF(table, i), saved.objid);
+	run_single_final(saved.final = RARRAY_AREF(table, i), saved.objid);
     }
     EC_POP_TAG();
 #undef RESTORE_FINALIZER
diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb
index b48fbc1..c26748f 100644
--- a/test/ruby/test_objectspace.rb
+++ b/test/ruby/test_objectspace.rb
@@ -161,6 +161,13 @@ End https://github.com/ruby/ruby/blob/trunk/test/ruby/test_objectspace.rb#L161
     END
   end
 
+  def test_exception_in_finalizer
+    assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], /finalizing \(RuntimeError\)/)
+    begin;
+      ObjectSpace.define_finalizer(Object.new) {raise "finalizing"}
+    end;
+  end
+
   def test_each_object
     klass = Class.new
     new_obj = klass.new
-- 
cgit v1.1


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

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