Project

General

Profile

Actions

Bug #18117

closed

Segmentation fault when yielding values from Ractors during GC sweeping

Added by vinistock (Vinicius Stock) about 3 years ago. Updated about 3 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 3.1.0dev (2021-08-16T08:00:19Z master a8714b83c4) [x86_64-linux]
[ruby-core:104976]

Description

Link for GitHub PR containing the 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

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]
Actions #1

Updated by vinistock (Vinicius Stock) about 3 years ago

  • Description updated (diff)

Updated by peterzhu2118 (Peter Zhu) about 3 years ago

  • Assignee set to peterzhu2118 (Peter Zhu)
  • Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN to 2.6: DONTNEED, 2.7: DONTNEED, 3.0: REQUIRED
Actions #3

Updated by peterzhu2118 (Peter Zhu) about 3 years ago

  • Status changed from Open to Closed

Applied in changeset git|bbedd29b6e98ef6e3fc2ce2b358d2b509b7cd1bb.


[Bug #18117] Fix Ractor race condition with GC

rb_objspace_reachable_objects_from requires that the GC not be active.
Since the Ractor barrier is not executed for incremental sweeping,
Ractor may call rb_objspace_reachable_objects_from after sweeping
has started to share objects. This causes a crash that looks like
the following:

<internal:ractor>:627: [BUG] rb_objspace_reachable_objects_from() is not supported while during_gc == true

Co-authored-by: Vinicius Stock

Updated by nagachika (Tomoyuki Chikanaga) about 3 years ago

  • Backport changed from 2.6: DONTNEED, 2.7: DONTNEED, 3.0: REQUIRED to 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONE

ruby_3_0 3fb51aec5ba7decffdfc32e540262aaae6167a95 merged revision(s) bbedd29b6e98ef6e3fc2ce2b358d2b509b7cd1bb.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0