Skip to content

Add missing write barrier in set_i_initialize_copy #13558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2025

Conversation

jhawthorn
Copy link
Member

This fixes a missing write barrier in the new Set implementation I detected with my new "wbcheck" tool (see #13557)

$ RUBY_GC_LIBRARY=wbcheck ./miniruby -e 'Set["a","b","c"].collect!(&:upcase)'
WBCHECK ERROR: Missed write barrier detected!
  Parent object: 0x50700001cdb0 (wb_protected: true)
    rb_obj_info_dump: (Set)set
  Reference counts - stored: 4, current: 4, missed: 3
  Missing reference to: 0x50400007f2d0
    rb_obj_info_dump: (String) len: 1, capa: 15 "A"
  Missing reference to: 0x50400007f350
    rb_obj_info_dump: (String) len: 1, capa: 15 "B"
  Missing reference to: 0x50400005f990
    rb_obj_info_dump: (String) len: 1, capa: 15 "C"

WBCHECK SUMMARY: Found 1 objects with missed write barriers (3 total violations)

It was a bit harder to reproduce with the standard GC, but I wanted to confirm this is a real issue and not a false-positive:

old_set = Set.new
3.times { GC.start }
old_set.replace(100.times.map { Object.new }.to_set)
GC.start(full_mark: false)
old_set.to_a.inspect
ruby --disable-gems test_set_wb.rb
test_set_wb.rb:5: [BUG] Segmentation fault at 0x0000000000000000
ruby 3.5.0dev (2025-05-26T20:44:05Z ractor_port 52248b13ff) +PRISM [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0004 p:---- s:0014 e:000013 CFUNC  :inspect
c:0003 p:---- s:0011 e:000010 CFUNC  :inspect
c:0002 p:0050 s:0007 E:001878 EVAL   test_set_wb.rb:5 [FINISH]
c:0001 p:0000 s:0003 E:001760 DUMMY  [FINISH]

-- Ruby level backtrace information ----------------------------------------
test_set_wb.rb:5:in '<main>'
test_set_wb.rb:5:in 'inspect'
test_set_wb.rb:5:in 'inspect'

When we copy the table from one set to another we need to run write
barriers.
@jhawthorn jhawthorn merged commit c962735 into ruby:master Jun 9, 2025
83 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants