mirror of
https://github.com/ruby/ruby.git
synced 2025-08-23 21:14:23 +02:00
Fix crash when GC runs during finalizers at shutdown
We need to remove from the finalizer_table after running all the finalizers because GC could trigger during the finalizer which could reclaim the finalizer table array. The following code crashes: 1_000_000.times do o = Object.new ObjectSpace.define_finalizer(o, proc { }) end
This commit is contained in:
parent
85f99b3828
commit
0610f1b083
Notes:
git
2024-08-14 17:50:13 +00:00
2 changed files with 16 additions and 2 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue