Project

General

Profile

Actions

Bug #22106

open

Getting a segfault when using finalizers and/or WeakMap in Ractors

Bug #22106: Getting a segfault when using finalizers and/or WeakMap in Ractors

Added by miles-georgi (Miles Georgi) 3 days ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [x86_64-linux]
[ruby-core:125706]

Description

If I run the following script I get a segfault:

def ractor_and_port_counts
  total_ractor_count = total_ractor_port_count = open_ractor_count = open_ractor_port_count = 0

  ObjectSpace.each_object do |object|
    case object
    when Ractor
      total_ractor_count += 1
      open_ractor_count += 1 unless object.default_port.closed?
    when Ractor::Port
      total_ractor_port_count += 1
      open_ractor_port_count += 1 unless object.closed?
    end
  end

  [total_ractor_count, open_ractor_count, total_ractor_port_count, open_ractor_port_count]
end

def show_ractor_counts
  GC.start
  pp ractor_and_port_counts
end

class Wrapper
  class << self
    def finalizer_proc
      proc do |id|
        wrapper_to_ractor = Ractor[:wrapper_to_ractor]

        if wrapper_to_ractor
          wrapper_to_ractor[id]&.each_key { |ractor| ractor << :close } rescue Ractor::ClosedError
        end
      end
    end

    def setup_finalizer(wrapper)
      wrapper_to_ractor = Ractor[:wrapper_to_ractor] ||= {}
      map = wrapper_to_ractor[wrapper.object_id] ||= ObjectSpace::WeakMap.new
      map[wrapper.ractor] = true

      ObjectSpace.define_finalizer(wrapper, &finalizer_proc)
    end
  end

  attr_reader :ractor

  def initialize(object)
    @ractor = Ractor.new do
      loop { break if receive == :close }

      o = nil
    end

    @ractor.send(object, move: true)

    self.class.setup_finalizer(self)
  end
end

class Outer
  def initialize = @inner = Wrapper.new(Inner.new)
end

class Inner; end

show_ractor_counts

outer = Wrapper.new(Outer.new)
show_ractor_counts

outer = nil
# Removing the following line makes it so it only segfaults sometimes instead of everytime
show_ractor_counts

I'll attach the script and the whole segfault but part of the segfault is:

<internal:gc>:44: [BUG] FL_FINALIZE flag is set, but finalizers are not found
ruby 4.0.5 (2026-05-20 revision 64336ffd0e) +PRISM [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0004 p:0010 s:0023 e:000018 l:y b:0001 METHOD <internal:gc>:44
c:0003 p:0004 s:0011 e:000010 l:y b:0001 METHOD test_scripts/finalizer-in-ractor-test-segfault:23
c:0002 p:0075 s:0007 E:000f98 l:n b:---- EVAL   test_scripts/finalizer-in-ractor-test-segfault:72 [FINISH]
c:0001 p:0000 s:0003 E:000b40 l:y b:---- DUMMY  [FINISH]

-- Ruby level backtrace information ----------------------------------------
test_scripts/finalizer-in-ractor-test-segfault:72:in '<main>'
test_scripts/finalizer-in-ractor-test-segfault:23:in 'show_ractor_counts'
<internal:gc>:44:in 'start'

This happens in both a local build of 4.1-dev and 4.0.5

I suspect one might need to put GC.start at the end of the script if unable to reproduce.


Files

segfault.txt (22 KB) segfault.txt output including segfault miles-georgi (Miles Georgi), 06/11/2026 05:45 PM
finalizer-in-ractor-test-segfault (1.66 KB) finalizer-in-ractor-test-segfault script to reproduce miles-georgi (Miles Georgi), 06/11/2026 05:45 PM

No data to display

Actions

Also available in: PDF Atom