mirror of
https://github.com/ruby/ruby.git
synced 2026-01-27 04:24:23 +00: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
@ -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…
x
Reference in New Issue
Block a user