Project

General

Profile

Actions

Bug #21664

open

Segfault when running Ractor tests in the same process

Bug #21664: Segfault when running Ractor tests in the same process

Added by Eregon (Benoit Daloze) about 15 hours ago. Updated about 15 hours ago.

Status:
Open
Assignee:
Target version:
-
ruby -v:
ruby 3.5.0dev (2025-11-01T19:14:42Z master 48c7f349f6) +PRISM [x86_64-linux]
[ruby-core:123651]

Description

When running the tests from https://github.com/ruby/ruby/blob/master/bootstraptest/test_ractor.rb in a single process, I see segfaults occurring every time on the following tests:

# move object with generic ivar
# move object with many generic ivars
# move object with complex generic ivars
# moved composite types move their non-shareable parts properly

To run those tests in the same process, I wrote a simple harness in https://github.com/eregon/ractor-shim/blob/main/test/run_tests.rb

Full reproduction steps:

git clone --branch ruby3.5-segfault-repro git@github.com:eregon/ractor-shim.git
cd ractor-shim
ruby test/run_tests.rb

Result:

Running test from line 1941: <internal:ractor>:743: [BUG] Object is missing entry in generic_fields_tbl
ruby 3.5.0dev (2025-11-01T19:14:42Z master 48c7f349f6) +PRISM [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0012 p:0003 s:0076 e:000075 l:y n:0001 METHOD <internal:ractor>:743
c:0011 p:0008 s:0069 e:000068 l:y n:0001 METHOD <internal:ractor>:330
c:0010 p:0045 s:0062 E:000648 l:n n:---- EVAL   /home/eregon/code/ractor-shim/test/test_ractor.rb:1946 [FINISH]
c:0009 p:---- s:0056 e:000055 l:y n:---- CFUNC  :eval
c:0008 p:0014 s:0048 e:000047 l:n n:---- BLOCK  test/run_tests.rb:128 [FINISH]
c:0007 p:---- s:0045 e:000044 l:y n:---- CFUNC  :catch
c:0006 p:0124 s:0040 e:000039 l:y n:0001 METHOD test/run_tests.rb:127
c:0005 p:0013 s:0024 E:001ca0 l:y n:0001 METHOD test/run_tests.rb:167
c:0004 p:1134 s:0016 e:000015 l:y n:0001 TOP    /home/eregon/code/ractor-shim/test/test_ractor.rb:1941 [FINISH]
c:0003 p:---- s:0012 e:000011 l:y n:---- CFUNC  :require_relative
c:0002 p:0107 s:0007 E:000cd8 l:n n:---- EVAL   test/run_tests.rb:192 [FINISH]
c:0001 p:0000 s:0003 E:0002d0 l:y n:---- DUMMY  [FINISH]

-- Ruby level backtrace information ----------------------------------------
test/run_tests.rb:192:in '<main>'
test/run_tests.rb:192:in 'require_relative'
/home/eregon/code/ractor-shim/test/test_ractor.rb:1941:in '<top (required)>'
test/run_tests.rb:167:in 'assert_equal'
test/run_tests.rb:127:in 'generic_assert'
test/run_tests.rb:127:in 'catch'
test/run_tests.rb:128:in 'block in generic_assert'
test/run_tests.rb:128:in 'eval'
/home/eregon/code/ractor-shim/test/test_ractor.rb:1946:in '<compiled>'
<internal:ractor>:330:in 'send'
<internal:ractor>:743:in 'send'

-- Threading information ---------------------------------------------------
Total ractor count: 2
Ruby thread count for this ractor: 1

-- C level backtrace information -------------------------------------------
/home/eregon/prefix/ruby-master/bin/ruby(rb_print_backtrace+0x14) [0x5630e371cb50] /home/eregon/code/ruby/vm_dump.c:1099
/home/eregon/prefix/ruby-master/bin/ruby(rb_vm_bugreport) /home/eregon/code/ruby/vm_dump.c:1444
/home/eregon/prefix/ruby-master/bin/ruby(rb_bug_without_die_internal+0x73) [0x5630e2fc554b] /home/eregon/code/ruby/error.c:1097
/home/eregon/prefix/ruby-master/bin/ruby(rb_bug) /home/eregon/code/ruby/error.c:1115
/home/eregon/prefix/ruby-master/bin/ruby(rb_imemo_fields_owner+0x0) [0x5630e2fa752b] /home/eregon/code/ruby/variable.c:1258
/home/eregon/prefix/ruby-master/bin/ruby(rb_obj_fields) /home/eregon/code/ruby/variable.c:1252
/home/eregon/prefix/ruby-master/bin/ruby(rb_shape_too_complex_p+0x0) [0x5630e31798f2] /home/eregon/code/ruby/variable.c:1812
/home/eregon/prefix/ruby-master/bin/ruby(imemo_fields_set) /home/eregon/code/ruby/variable.c:1766
/home/eregon/prefix/ruby-master/bin/ruby(generic_field_set) /home/eregon/code/ruby/variable.c:1813
/home/eregon/prefix/ruby-master/bin/ruby(RB_BUILTIN_TYPE+0x0) [0x5630e2fe8096] /home/eregon/code/ruby/gc.c:1900
/home/eregon/prefix/ruby-master/bin/ruby(rbimpl_RB_TYPE_P_fastpath) ./include/ruby/internal/value_type.h:352
/home/eregon/prefix/ruby-master/bin/ruby(RB_TYPE_P) ./include/ruby/internal/value_type.h:379
/home/eregon/prefix/ruby-master/bin/ruby(RBASIC_SHAPE_ID) ./shape.h:145
/home/eregon/prefix/ruby-master/bin/ruby(object_id0) /home/eregon/code/ruby/gc.c:1902
/home/eregon/prefix/ruby-master/bin/ruby(object_id0) /home/eregon/code/ruby/gc.c:1888
/home/eregon/prefix/ruby-master/bin/ruby(rb_gc_obj_id_moved+0x72) [0x5630e2fe8d52] /home/eregon/code/ruby/gc.c:2178
/home/eregon/prefix/ruby-master/bin/ruby(RB_IMMEDIATE_P+0x0) [0x5630e30943d0] /home/eregon/code/ruby/ractor.c:1977
/home/eregon/prefix/ruby-master/bin/ruby(RB_SPECIAL_CONST_P) ./include/ruby/internal/special_consts.h:329
/home/eregon/prefix/ruby-master/bin/ruby(rb_type) ./include/ruby/internal/value_type.h:227
/home/eregon/prefix/ruby-master/bin/ruby(rb_obj_exivar_p) /home/eregon/code/ruby/shape.h:422
/home/eregon/prefix/ruby-master/bin/ruby(move_leave) /home/eregon/code/ruby/ractor.c:1979
/home/eregon/prefix/ruby-master/bin/ruby(obj_traverse_replace_i+0x282) [0x5630e3097852] /home/eregon/code/ruby/ractor.c:1896
/home/eregon/prefix/ruby-master/bin/ruby(rb_obj_traverse_replace+0x46) [0x5630e3097f93] /home/eregon/code/ruby/ractor.c:1920
/home/eregon/prefix/ruby-master/bin/ruby(ractor_move) /home/eregon/code/ruby/ractor.c:1995
/home/eregon/prefix/ruby-master/bin/ruby(ractor_prepare_payload) /home/eregon/code/ruby/ractor_sync.c:787
/home/eregon/prefix/ruby-master/bin/ruby(ractor_basket_new) /home/eregon/code/ruby/ractor_sync.c:803
/home/eregon/prefix/ruby-master/bin/ruby(ractor_send0) /home/eregon/code/ruby/ractor_sync.c:1210
/home/eregon/prefix/ruby-master/bin/ruby(ractor_send) /home/eregon/code/ruby/ractor_sync.c:1219
/home/eregon/prefix/ruby-master/bin/ruby(ractor_port_send) /home/eregon/code/ruby/ractor_sync.c:150
/home/eregon/prefix/ruby-master/bin/ruby(builtin_inline_class_743) /home/eregon/code/ruby/ractor.rb:744
/home/eregon/prefix/ruby-master/bin/ruby(vm_pop_frame+0x0) [0x5630e31b148e] /home/eregon/code/ruby/vm_insnhelper.c:7550
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_core) /home/eregon/code/ruby/insns.def:1677
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_loop+0x52) [0x5630e31a1e0a] /home/eregon/code/ruby/vm.c:2769
/home/eregon/prefix/ruby-master/bin/ruby(rb_vm_exec) /home/eregon/code/ruby/vm.c:2745
/home/eregon/prefix/ruby-master/bin/ruby(rb_f_eval+0x163) [0x5630e31bc783] /home/eregon/code/ruby/vm_eval.c:2026
/home/eregon/prefix/ruby-master/bin/ruby(vm_cfp_consistent_p+0x0) [0x5630e3198f0d] /home/eregon/code/ruby/vm_insnhelper.c:3915
/home/eregon/prefix/ruby-master/bin/ruby(vm_call_cfunc_with_frame_) /home/eregon/code/ruby/vm_insnhelper.c:3917
/home/eregon/prefix/ruby-master/bin/ruby(vm_sendish+0x15f) [0x5630e3196d7f] /home/eregon/code/ruby/vm_insnhelper.c:6108
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_core+0x86) [0x5630e31b0e86] /home/eregon/code/ruby/insns.def:902
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_loop+0x52) [0x5630e31a1e0a] /home/eregon/code/ruby/vm.c:2769
/home/eregon/prefix/ruby-master/bin/ruby(rb_vm_exec) /home/eregon/code/ruby/vm.c:2745
/home/eregon/prefix/ruby-master/bin/ruby(catch_i+0xf7) [0x5630e31a6a07] /home/eregon/code/ruby/vm.c:1823
/home/eregon/prefix/ruby-master/bin/ruby(vm_catch_protect+0x118) [0x5630e319a6f8] /home/eregon/code/ruby/vm_eval.c:2634
/home/eregon/prefix/ruby-master/bin/ruby(rb_catch_obj+0x4a) [0x5630e319aa4f] /home/eregon/code/ruby/vm_eval.c:2660
/home/eregon/prefix/ruby-master/bin/ruby(rb_f_catch) /home/eregon/code/ruby/vm_eval.c:2610
/home/eregon/prefix/ruby-master/bin/ruby(vm_cfp_consistent_p+0x0) [0x5630e3198f0d] /home/eregon/code/ruby/vm_insnhelper.c:3915
/home/eregon/prefix/ruby-master/bin/ruby(vm_call_cfunc_with_frame_) /home/eregon/code/ruby/vm_insnhelper.c:3917
/home/eregon/prefix/ruby-master/bin/ruby(vm_sendish+0x15f) [0x5630e3196d7f] /home/eregon/code/ruby/vm_insnhelper.c:6108
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_core+0x147) [0x5630e31b0f47] /home/eregon/code/ruby/insns.def:854
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_loop+0x52) [0x5630e31a1e0a] /home/eregon/code/ruby/vm.c:2769
/home/eregon/prefix/ruby-master/bin/ruby(rb_vm_exec) /home/eregon/code/ruby/vm.c:2745
/home/eregon/prefix/ruby-master/bin/ruby(require_internal+0x10b2) [0x5630e303fe62] /home/eregon/code/ruby/load.c:1353
/home/eregon/prefix/ruby-master/bin/ruby(rb_require_string_internal+0x6e) [0x5630e303ff6e] /home/eregon/code/ruby/load.c:1464
/home/eregon/prefix/ruby-master/bin/ruby(vm_cfp_consistent_p+0x0) [0x5630e3198f0d] /home/eregon/code/ruby/vm_insnhelper.c:3915
/home/eregon/prefix/ruby-master/bin/ruby(vm_call_cfunc_with_frame_) /home/eregon/code/ruby/vm_insnhelper.c:3917
/home/eregon/prefix/ruby-master/bin/ruby(vm_sendish+0x15f) [0x5630e3196d7f] /home/eregon/code/ruby/vm_insnhelper.c:6108
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_core+0x86) [0x5630e31b0e86] /home/eregon/code/ruby/insns.def:902
/home/eregon/prefix/ruby-master/bin/ruby(vm_exec_loop+0x52) [0x5630e31a1e0a] /home/eregon/code/ruby/vm.c:2769
/home/eregon/prefix/ruby-master/bin/ruby(rb_vm_exec) /home/eregon/code/ruby/vm.c:2745
/home/eregon/prefix/ruby-master/bin/ruby(rb_ec_exec_node+0xd9) [0x5630e2fc9d99] /home/eregon/code/ruby/eval.c:283
/home/eregon/prefix/ruby-master/bin/ruby(ruby_run_node+0x80) [0x5630e2fce470] /home/eregon/code/ruby/eval.c:321
/home/eregon/prefix/ruby-master/bin/ruby(rb_main+0x21) [0x5630e2fc7180] ./main.c:42
/home/eregon/prefix/ruby-master/bin/ruby(main) ./main.c:62
/lib64/libc.so.6(__libc_start_call_main+0x78) [0x7fc19cb8b448]
/lib64/libc.so.6(__libc_start_main+0x8b) [0x7fc19cb8b50b]
[0x5630e2fc71c5]

-- Other runtime information -----------------------------------------------
...

Updated by Eregon (Benoit Daloze) about 15 hours ago Actions #1 [ruby-core:123652]

Once this bug is fixed I think it would be valuable to run these tests together in the same process, as that's a much stronger test than running tiny pieces of code each in their own process (what the bootstrap test harness does).
Notably if something goes wrong it might just get unnoticed if the process shuts down soon after it, but would get noticed if more tests and/or GC run after it.
I think this is why these segfaults only appear when running in the same process here.

Ideally we'd also run Ractor tests with the rest of test-all, but that requires Ractor to be fully compatible first (e.g. fix ObjectSpace.each_object with multiple Ractors to be compatible, e.g. by using a transitive reachable_objects_from).

Actions

Also available in: PDF Atom