Bug #18117
Updated by vinistock (Vinicius Stock) over 3 years ago
[Link for GitHub PR containing the fix](https://github.com/ruby/ruby/pull/4755) fix]() Ractors may invoke `rb_objspace_reachable_objects_from` when yielding values back to the main-Ractor. If this occurs during a sweeping pass of the GC, then it might lead to a segmentation fault. The following script creates a worker pool. For each worker, we create some dummy objects to make GC trigger eventually and then we yield back `Time.now`. Within a few iterations, the scenario occurs and a segmentation fault is thrown. **Reproduction script** ```ruby workers = (0...8).map do Ractor.new do loop do 10_000.times.map { Object.new } Ractor.yield Time.now end end end 1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) } ``` **Backtrace** ``` <internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. <internal:ractor>:627: [BUG] rb_objspace_reachable_objects_from() is not supported while during_gc == true ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin20] -- Crash Report log information -------------------------------------------- See Crash Report log file under the one of following: * ~/Library/Logs/DiagnosticReports * /Library/Logs/DiagnosticReports for more details. Don't forget to include the above Crash Report log file in bug reports. -- Control frame information ----------------------------------------------- c:0005 p:0003 s:0020 e:000019 METHOD <internal:ractor>:627 c:0004 p:0032 s:0013 e:000012 BLOCK example.rb:5 [FINISH] c:0003 p:---- s:0010 e:000009 CFUNC :loop c:0002 p:0005 s:0006 e:000005 BLOCK example.rb:3 [FINISH] c:0001 p:---- s:0003 e:000002 (none) [FINISH] -- Ruby level backtrace information ---------------------------------------- example.rb:3:in `block (2 levels) in <main>' example.rb:3:in `loop' example.rb:5:in `block (3 levels) in <main>' <internal:ractor>:627:in `yield' -- C level backtrace information ------------------------------------------- /opt/rubies/3.0.2/bin/ruby(rb_vm_bugreport+0x6cf) [0x10e1f60bf] /opt/rubies/3.0.2/bin/ruby(rb_bug_without_die+0x184) [0x10e010914] /opt/rubies/3.0.2/bin/ruby(rb_bug+0x6f) [0x10e202ec9] /opt/rubies/3.0.2/bin/ruby(rb_objspace_reachable_objects_from.cold.1+0x12) [0x10e203522] /opt/rubies/3.0.2/bin/ruby(rb_objspace_reachable_objects_from+0xce) [0x10e032a2e] /opt/rubies/3.0.2/bin/ruby(obj_traverse_replace_i+0x3c9) [0x10e0ff369] /opt/rubies/3.0.2/bin/ruby(ractor_basket_setup+0x1b9) [0x10e0febf9] /opt/rubies/3.0.2/bin/ruby(ractor_select+0x1c6) [0x10e1005f6] /opt/rubies/3.0.2/bin/ruby(builtin_inline_class_627+0x3e) [0x10e0fd01e] /opt/rubies/3.0.2/bin/ruby(vm_exec_core+0x8d4c) [0x10e1cdbec] /opt/rubies/3.0.2/bin/ruby(rb_vm_exec+0xcab) [0x10e1def1b] /opt/rubies/3.0.2/bin/ruby(invoke_block_from_c_bh+0x70c) [0x10e1efcdc] /opt/rubies/3.0.2/bin/ruby(loop_i+0x4c) [0x10e1f069c] /opt/rubies/3.0.2/bin/ruby(rb_vrescue2+0x181) [0x10e01c981] /opt/rubies/3.0.2/bin/ruby(rb_rescue2+0x7b) [0x10e01c7db] /opt/rubies/3.0.2/bin/ruby(vm_call_cfunc_with_frame+0x14f) [0x10e1ebbef] /opt/rubies/3.0.2/bin/ruby(vm_sendish+0x516) [0x10e1e3806] /opt/rubies/3.0.2/bin/ruby(vm_exec_core+0x399d) [0x10e1c883d] /opt/rubies/3.0.2/bin/ruby(rb_vm_exec+0xcab) [0x10e1def1b] /opt/rubies/3.0.2/bin/ruby(vm_invoke_proc+0x809) [0x10e1dd339] /opt/rubies/3.0.2/bin/ruby(thread_do_start_proc+0x1e3) [0x10e1980f3] /opt/rubies/3.0.2/bin/ruby(thread_start_func_2+0x490) [0x10e197a70] /opt/rubies/3.0.2/bin/ruby(thread_start_func_1+0x10d) [0x10e19741d] /usr/lib/system/libsystem_pthread.dylib(_pthread_start+0xe0) [0x7fff2049b8fc] ```