From: "byroot (Jean Boussier) via ruby-core" Date: 2025-05-14T13:52:47+00:00 Subject: [ruby-core:122092] [Ruby Bug#17677] Ractor crashes fork when blocking Issue #17677 has been updated by byroot (Jean Boussier). Status changed from Assigned to Closed I can't reproduce on master nor on any version since 3.0.3. I'm going to assume this was fixed. ---------------------------------------- Bug #17677: Ractor crashes fork when blocking https://bugs.ruby-lang.org/issues/17677#change-113246 * Author: delner (David Elner) * Status: Closed * Assignee: ractor * ruby -v: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- ## Background If you create a Ractor which blocks (e.g. `receive`), then fork the process, the fork will segfault upon completion. ## How to reproduce ```ruby r2 = Ractor.new do Ractor.receive end sleep(1) puts "Forking..." fork do sleep(1) puts "End fork." end loop do puts "Main thread." sleep(1) end ``` ## Expectation and result Application prints ���Main thread��� from main process every second, while fork prints ���End fork.��� then produces a segfault. Main process continues to run. Expected fork to not raise a segfault. ``` :267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. Forking... Main thread. Main thread. End fork. app/sandbox.rb:80: [BUG]: Device or resource busy (EBUSY) ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux] -- Control frame information ----------------------------------------------- c:0003 p:---- s:0011 e:000010 CFUNC :fork c:0002 p:0048 s:0007 E:001b48 EVAL app/sandbox.rb:80 [FINISH] c:0001 p:0000 s:0003 E:002590 (none) [FINISH] -- Ruby level backtrace information ---------------------------------------- app/sandbox.rb:80:in `
' app/sandbox.rb:80:in `fork' -- C level backtrace information ------------------------------------------- /usr/local/lib/libruby.so.3.0(rb_print_backtrace+0x11) [0x7f9848528cfb] vm_dump.c:758 /usr/local/lib/libruby.so.3.0(rb_vm_bugreport) vm_dump.c:998 /usr/local/lib/libruby.so.3.0(bug_report_end+0x0) [0x7f9848354808] error.c:763 /usr/local/lib/libruby.so.3.0(rb_bug_without_die) error.c:763 /usr/local/lib/libruby.so.3.0(die+0x0) [0x7f98482c6902] error.c:771 /usr/local/lib/libruby.so.3.0(rb_bug) error.c:773 /usr/local/lib/libruby.so.3.0(rb_bug_errno+0x3c) [0x7f9848354a1c] error.c:802 /usr/local/lib/libruby.so.3.0(rb_native_mutex_destroy+0x20) [0x7f98484ce380] thread_pthread.c:444 /usr/local/lib/libruby.so.3.0(rb_native_cond_initialize) (null):0 /usr/local/lib/libruby.so.3.0(ractor_free+0xd) [0x7f984844487d] ractor.c:229 /usr/local/lib/libruby.so.3.0(run_final+0xb) [0x7f9848371c66] gc.c:3670 /usr/local/lib/libruby.so.3.0(finalize_list) gc.c:3689 /usr/local/lib/libruby.so.3.0(rb_objspace_call_finalizer+0x33d) [0x7f984837cc5d] gc.c:3852 /usr/local/lib/libruby.so.3.0(rb_ec_cleanup+0x311) [0x7f984835f0b1] eval.c:184 /usr/local/lib/libruby.so.3.0(ruby_stop+0x9) [0x7f984835f339] eval.c:329 /usr/local/lib/libruby.so.3.0(rb_f_fork+0x1f) [0x7f98484402f8] process.c:4348 /usr/local/lib/libruby.so.3.0(rb_f_fork) process.c:4338 /usr/local/lib/libruby.so.3.0(vm_call_cfunc_with_frame+0x11b) [0x7f984850672b] vm_insnhelper.c:2898 /usr/local/lib/libruby.so.3.0(vm_call_method_each_type+0xf9) [0x7f98485192c9] vm_insnhelper.c:3388 /usr/local/lib/libruby.so.3.0(vm_call_method+0xb4) [0x7f9848519b24] vm_insnhelper.c:3506 /usr/local/lib/libruby.so.3.0(vm_sendish+0xb3) [0x7f984850a3d3] vm_insnhelper.c:4499 /usr/local/lib/libruby.so.3.0(vm_exec_core+0x140) [0x7f98485123e0] insns.def:770 /usr/local/lib/libruby.so.3.0(rb_vm_exec+0x176) [0x7f9848517b26] vm.c:2163 /usr/local/lib/libruby.so.3.0(rb_ec_exec_node+0xd9) [0x7f9848359719] eval.c:317 /usr/local/lib/libruby.so.3.0(ruby_run_node+0x55) [0x7f984835f395] eval.c:375 /usr/local/bin/ruby(main+0x5b) [0x565147e5410b] ./main.c:50 ... Main thread. Main thread. Main thread. ``` ## Additional notes This does not happen if a blocking operation does not occur in the Ractor. E.g. ```ruby r2 = Ractor.new do loop { puts "[#{Process.pid}] Ractor"; sleep(1) } end ``` Segfault can also be prevented by invoking `close_incoming` prior to forking, although this raises another error internally. It also does not crash on MacOS 10.15.7: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]. ## Suggested solutions (None) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/