Project

General

Profile

Bug #18117

Updated by vinistock (Vinicius Stock) over 2 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] 
 ```

Back