diff --git a/gc/default.c b/gc/default.c index 1ecffe9b1d..5c0c2b1386 100644 --- a/gc/default.c +++ b/gc/default.c @@ -3251,12 +3251,12 @@ rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr) while (list) { struct force_finalize_list *curr = list; + rb_gc_run_obj_finalizer(rb_gc_impl_object_id(objspace, curr->obj), RARRAY_LEN(curr->table), get_final, (void *)curr->table); + st_data_t obj = (st_data_t)curr->obj; st_delete(finalizer_table, &obj, 0); FL_UNSET(curr->obj, FL_FINALIZE); - rb_gc_run_obj_finalizer(rb_gc_impl_object_id(objspace, curr->obj), RARRAY_LEN(curr->table), get_final, (void *)curr->table); - list = curr->next; xfree(curr); } diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb index 1c97bd517e..d3ce6e6ed5 100644 --- a/test/ruby/test_objectspace.rb +++ b/test/ruby/test_objectspace.rb @@ -101,6 +101,20 @@ End ObjectSpace.define_finalizer(a) { p :ok } !b END + + assert_in_out_err(["-e", <<~RUBY], "", %w(:ok :ok), []) + a = Object.new + ObjectSpace.define_finalizer(a) { p :ok } + + 1_000_000.times do + o = Object.new + ObjectSpace.define_finalizer(o) { } + end + + b = Object.new + ObjectSpace.define_finalizer(b) { p :ok } + RUBY + assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) } code = proc do |priv|