From 3e06a73609ce9cf88fcef777fa20a407767701b7 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 22 Apr 2025 18:55:55 +0900 Subject: [PATCH 1/2] Add missing lock in `rb_gc_impl_define_finalizer` `objspace->finalizer_table` must be synchronized, otherwise concurrent insertion from multiple ractors will cause a crash. Repro: ```ruby ractors = 5.times.map do |i| Ractor.new do 100_000.times.map do o = Object.new ObjectSpace.define_finalizer(o, ->(id) {}) o end end end ractors.each(&:take) ``` --- gc/mmtk/mmtk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index b844c8c..70df475 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -973,6 +973,8 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block) RBASIC(obj)->flags |= FL_FINALIZE; + int lev = rb_gc_vm_lock(); + if (st_lookup(objspace->finalizer_table, obj, &data)) { table = (VALUE)data; @@ -997,6 +999,8 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block) st_add_direct(objspace->finalizer_table, obj, table); } + rb_gc_vm_unlock(lev); + return block; } From 6012525bf45dacf3254e37ae2f6e62ced3f294fd Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 23 Apr 2025 07:04:09 +0200 Subject: [PATCH 2/2] rb_gc_impl_define_finalizer: unlock on early return --- gc/mmtk/mmtk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gc/mmtk/mmtk.c b/gc/mmtk/mmtk.c index 70df475..d74bce7 100644 --- a/gc/mmtk/mmtk.c +++ b/gc/mmtk/mmtk.c @@ -986,6 +986,7 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block) for (i = 0; i < len; i++) { VALUE recv = RARRAY_AREF(table, i); if (rb_equal(recv, block)) { + rb_gc_vm_unlock(lev); return recv; } }