Project

General

Profile

Actions

Bug #22084

closed

invokesuper from define_method in Ractor can call wrong super method or crash

Bug #22084: invokesuper from define_method in Ractor can call wrong super method or crash

Added by jhawthorn (John Hawthorn) about 1 month ago. Updated about 1 month ago.

Status:
Closed
Assignee:
Target version:
-
ruby -v:
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [arm64-darwin25]
[ruby-core:125581]

Description

vm_search_super_method has an odd behaviour where it allocates new callinfo (ci) and assigns it back to the iseq. All of our other method calls only reassign the callcache (cc). Because this CI is used from the iseq immediately after for method lookup or even later for the name in method_missing.

N = Integer(ENV.fetch("N", "1000000"))

class Base
  def method_missing(mid, *) = mid
end

class Child < Base
  BODY = Ractor.shareable_proc { super() }
  define_method(:foo, &BODY)
  define_method(:bar, &BODY)
end

[:foo, :bar].map do |mid|
  Ractor.new(mid) do |mid|
    obj = Child.new
    N.times do
      got = obj.__send__(mid)
      raise "#{mid} returned #{got.inspect}" unless got == mid
    end
  end
end.each(&:value)

This will eventually result in method_missing being called with the wrong name

Another test also crashes on my arm-based M4 macbook pro. Which I think may be a memory ordering issue of the newly allocated callcache:

N = Integer(ENV.fetch("N", "1000000"))

class Base
  def foo = :foo
  def bar = :bar
end

class Child < Base
  BODY = Ractor.shareable_proc { super() }
  define_method(:foo, &BODY)
  define_method(:bar, &BODY)
end

[:foo, :bar].map do |mid|
  Ractor.new(mid) do |mid|
    obj = Child.new
    N.times do
      got = obj.__send__(mid)
      raise "#{mid} returned #{got.inspect}" unless got == mid
    end
  end
end.each(&:value)

https://github.com/ruby/ruby/pull/17127


Related issues 1 (0 open1 closed)

Related to Ruby - Bug #22075: heap-use-after-free in `rb_vm_ci_lookup` under parallel RactorsClosedractorActions

Updated by jhawthorn (John Hawthorn) about 1 month ago Actions #1

  • Related to Bug #22075: heap-use-after-free in `rb_vm_ci_lookup` under parallel Ractors added

Updated by jhawthorn (John Hawthorn) about 1 month ago Actions #2

  • Description updated (diff)

Updated by jhawthorn (John Hawthorn) about 1 month ago Actions #3

  • Description updated (diff)

Updated by jhawthorn (John Hawthorn) about 1 month ago Actions #4

  • Status changed from Open to Closed

Applied in changeset git|4f6c8c693c9712d81a298bcae5f3a6e30616432f.


Use stack callinfo/calldata for super dispatch

Previously vm_search_super_method would allocate a new callinfo and
write it back into the iseq's call data. Because iseqs can be shared
between Ractors (e.g. via Ractor.shareable_proc + define_method), two
Ractors invoking super through the same iseq could race on the ci/cc,
producing wrong dispatch or crashes from torn callcache reads on
weakly-ordered architectures.

Build the adjusted callinfo on the stack instead, mirroring
sendforward/invokesuperforward. The callcache is also loaded and stored
back with acquire/release atomics so it can be safely shared.

[Bug #22084]

Actions

Also available in: PDF Atom