[ruby-core:127019] [Ruby Bug#22419] [BUG] "rb_objspace_reachable_objects_from_local: set is owned by another Ractor" when a non-main Ractor reads a class instance variable since f0439cdfa7
Issue #22419 has been reported by yahonda (Yasuo Honda). ---------------------------------------- Bug #22419: [BUG] "rb_objspace_reachable_objects_from_local: set is owned by another Ractor" when a non-main Ractor reads a class instance variable since f0439cdfa7 https://bugs.ruby-lang.org/issues/22419 * Author: yahonda (Yasuo Honda) * Status: Open * ruby -v: ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- The Rails nightly CI against Ruby master started crashing with `[BUG] rb_objspace_reachable_objects_from_local: set is owned by another Ractor` in Action Pack and Action View on all of master, YJIT and master-debug. It bisects to f0439cdfa7 ("Remove VM lock from Ractor.make_shareable()", https://github.com/ruby/ruby/pull/19145): reading a class instance variable that holds a frozen `Set` created on the main Ractor from a non-main Ractor crashes. The crash happens where a non-main Ractor reads class-level state such as `AbstractController::Base.action_methods` (a frozen `Set` memoized in a class instance variable) and `Mime::Type`'s registry: https://buildkite.com/rails/rails-nightly/builds/4809#01a11d51-060e-49c8-bdc... The full log of that Action Pack job is attached (rails-nightly_build_4809_actionpack-master.log.zip). It can be reproduced with a single Action Pack test: ``` cd actionpack && bin/test test/controller/base_test.rb -i test_action_methods_is_ractor_safe_by_default ``` ## Steps to reproduce ```ruby class C @s = Set[1, 2].freeze class << self; attr_reader :s; end end p Ractor.new { C.s.include?(1) }.value ``` ## Expected behavior ``` $ ruby -v ruby 4.1.0dev (2026-10-06T21:11:37Z master e8964f3aa3) +PRISM [x86_64-linux] $ ruby rep.rb rep.rb:5: warning: Ractor API is experimental and may change in future versions of Ruby. true ``` ## Actual behavior ``` $ ruby -v ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] $ ruby rep.rb rep.rb:5: warning: Ractor API is experimental and may change in future versions of Ruby. rep.rb:5: [BUG] rb_objspace_reachable_objects_from_local: set is owned by another Ractor ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] -- Ruby level backtrace information ---------------------------------------- rep.rb:5:in 'block in <main>' -- Threading information --------------------------------------------------- Total ractor count: 2 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- ruby(rb_print_backtrace+0x11) vm_dump.c:1117 ruby(rb_vm_bugreport) vm_dump.c:1483 ruby(rb_bug_without_die_internal+0xbe) error.c:1150 ruby(rb_bug) error.c:1168 ruby(...) gc.c:5948 ruby(obj_traverse_reachable+0x2b) ractor.c:1687 ruby(obj_traverse_i) ractor.c:1825 ruby(rb_obj_traverse+0x2c) ractor.c:1875 ruby(rb_ractor_shareable_p_continue) ractor.c:2081 ruby(rb_ractor_shareable_p+0x1b) ./include/ruby/ractor.h:280 ruby(rb_ractor_shareable_p) ./include/ruby/ractor.h:269 ruby(rb_ivar_lookup) variable.c:1626 ruby(vm_sendish+0xae) vm_insnhelper.c:6285 ... ``` ---Files-------------------------------- rails-nightly_build_4809_actionpack-master.log.zip (168 KB) -- https://bugs.ruby-lang.org/
Issue #22419 has been updated by luke-gru (Luke Gruber). Thanks for the report. We're working on fixing this and have an I've created a [PR](https://github.com/ruby/ruby/pull/19283) for it. We've realized that the way Ractor shareability is checked when the object is not shareable but frozen is currently buggy and needs to be fixed. For example, this crashes today: ```ruby # Repro: a non-owner Ractor reading a class ivar runs the full shareability traversal # on the owner's object graph (rb_ivar_lookup -> rb_ractor_shareable_p -> # rb_obj_traverse -> mark_shareable -> rb_str_make_independent). Several readers do it # at once on the same STR_SHARED strings, racing in str_make_independent_expand: # one clears STR_SHARED and installs a new heap.ptr while another, holding the old # pointer, re-tests the flags and frees it. # # Crashes on master (double free / "pointer being freed was not allocated"), usually on # the first round. Fixed by the owner-only promotion branch, where the foreign read is # a flag test. Run with MallocScribble=1 for a cleaner failure. N_STR = (ENV['N_STR'] || 20_000).to_i N_RACT = (ENV['N_RACT'] || 8).to_i ROUNDS = (ENV['ROUNDS'] || 50).to_i BASE = ("abcdefghij" * 200).freeze # long enough that substrings are STR_SHARED ROUNDS.times do |round| k = Class.new do class << self; attr_accessor :v; end end Object.const_set(:"C#{round}", k) k.v = Array.new(N_STR) { |i| BASE[(i % 100)..].freeze }.freeze start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 0.05 rs = N_RACT.times.map do Ractor.new(k, start) do |kls, t0| nil while Process.clock_gettime(Process::CLOCK_MONOTONIC) < t0 a = kls.v # <- traverses + promotes the owner's graph a.size + a[0].length end end rs.each(&:value) $stderr.print "." if round % 10 == 0 end $stderr.puts "\nsurvived #{ROUNDS} rounds" ``` ---------------------------------------- Bug #22419: [BUG] "rb_objspace_reachable_objects_from_local: set is owned by another Ractor" when a non-main Ractor reads a class instance variable since f0439cdfa7 https://bugs.ruby-lang.org/issues/22419#change-119485 * Author: yahonda (Yasuo Honda) * Status: Open * Assignee: ractor * ruby -v: ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- The Rails nightly CI against Ruby master started crashing with `[BUG] rb_objspace_reachable_objects_from_local: set is owned by another Ractor` in Action Pack and Action View on all of master, YJIT and master-debug. It bisects to f0439cdfa7 ("Remove VM lock from Ractor.make_shareable()", https://github.com/ruby/ruby/pull/19145): reading a class instance variable that holds a frozen `Set` created on the main Ractor from a non-main Ractor crashes. The crash happens where a non-main Ractor reads class-level state such as `AbstractController::Base.action_methods` (a frozen `Set` memoized in a class instance variable) and `Mime::Type`'s registry: https://buildkite.com/rails/rails-nightly/builds/4809#01a11d51-060e-49c8-bdc... The full log of that Action Pack job is attached (rails-nightly_build_4809_actionpack-master.log.zip). It can be reproduced with a single Action Pack test: ``` cd actionpack && bin/test test/controller/base_test.rb -i test_action_methods_is_ractor_safe_by_default ``` ## Steps to reproduce ```ruby class C @s = Set[1, 2].freeze class << self; attr_reader :s; end end p Ractor.new { C.s.include?(1) }.value ``` ## Expected behavior ``` $ ruby -v ruby 4.1.0dev (2026-10-06T21:11:37Z master e8964f3aa3) +PRISM [x86_64-linux] $ ruby rep.rb rep.rb:5: warning: Ractor API is experimental and may change in future versions of Ruby. true ``` ## Actual behavior ``` $ ruby -v ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] $ ruby rep.rb rep.rb:5: warning: Ractor API is experimental and may change in future versions of Ruby. rep.rb:5: [BUG] rb_objspace_reachable_objects_from_local: set is owned by another Ractor ruby 4.1.0dev (2026-10-06T22:31:56Z master f0439cdfa7) +PRISM [x86_64-linux] -- Ruby level backtrace information ---------------------------------------- rep.rb:5:in 'block in <main>' -- Threading information --------------------------------------------------- Total ractor count: 2 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- ruby(rb_print_backtrace+0x11) vm_dump.c:1117 ruby(rb_vm_bugreport) vm_dump.c:1483 ruby(rb_bug_without_die_internal+0xbe) error.c:1150 ruby(rb_bug) error.c:1168 ruby(...) gc.c:5948 ruby(obj_traverse_reachable+0x2b) ractor.c:1687 ruby(obj_traverse_i) ractor.c:1825 ruby(rb_obj_traverse+0x2c) ractor.c:1875 ruby(rb_ractor_shareable_p_continue) ractor.c:2081 ruby(rb_ractor_shareable_p+0x1b) ./include/ruby/ractor.h:280 ruby(rb_ractor_shareable_p) ./include/ruby/ractor.h:269 ruby(rb_ivar_lookup) variable.c:1626 ruby(vm_sendish+0xae) vm_insnhelper.c:6285 ... ``` ---Files-------------------------------- rails-nightly_build_4809_actionpack-master.log.zip (168 KB) -- https://bugs.ruby-lang.org/
participants (2)
-
luke-gru (Luke Gruber) -
yahonda (Yasuo Honda)