Actions
Bug #21368
open
Moving objects with finalizer between Ractors crashes
Description
When an object is moved to a different Ractor, the finalizers are not copied to the new object, so it will have the FL_FINALIZE
flag set but no entry in the finalizer table.
The following script crashes:
r = Ractor.new do
loop { Ractor.receive }
end
1_000.times do
o = Object.new
ObjectSpace.define_finalizer(o, proc { |id| })
r.send(o, move: true)
end
Files
Updated by peterzhu2118 (Peter Zhu) 5 days ago
- Assignee set to ractor
Updated by zzak (zzak _) 1 day ago
It seemed fun to patch, but I'm not sure this is correct:
https://github.com/ruby/ruby/pull/13452
Updated by hsbt (Hiroshi SHIBATA) about 17 hours ago
- Status changed from Open to Assigned
Updated by osyoyu (Daisuke Aritomo) about 8 hours ago
- File 0001-Bug-21368-Transfer-finalizer-when-moving-between-Rac.patch 0001-Bug-21368-Transfer-finalizer-when-moving-between-Rac.patch added
The script in the description didn't crash in my environments (the following). Explicitly calling GC.start
did.
- Linux
ruby 3.5.0dev (2025-05-28T04:34:40Z master d064fd067b) +PRISM [x86_64-linux]
- macOS
ruby 3.5.0dev (2025-05-28T04:34:40Z master d064fd067b) +PRISM [arm64-darwin24]
r = Ractor.new do
Ractor.receive # don't bind to a variable (let it be garbage collected)
GC.start
end
o = Object.new
ObjectSpace.define_finalizer(o, proc { |id| })
r.send(o, move: true)
r.take
I have attached an updated version of @zzak (zzak _)_'s patch which resolves this crash, but I suppose this is inappropiate since this will leak outer variables in the following case:
r = Ractor.new do
Ractor.receive
GC.start # `unshareable` happens to get read in this Ractor
end
o = Object.new
unshareable = +"hello"
ObjectSpace.define_finalizer(o, proc { |id| p unshareable })
r.send(o, move: true)
r.take
Maybe simply marking objects with a finalizer ineligible for moving is more appropiate.
Actions
Like0
Like0Like0Like0Like0