Disallow forking from non-main ractor

[Bug #17516]

`fork(2)` only leave the calling thread alive in the child.
Because of this forking from the non-main ractor can easily
leave the VM in a corrupted state.

It may be possible in the future to carefully allow forking from non-main
Ractor, but shot term it's preferable to add this restriction.
This commit is contained in:
Jean Boussier 2025-06-24 12:33:27 +02:00
parent 45a2c95d0f
commit 5bcc639b34
3 changed files with 17 additions and 0 deletions

View file

@ -14057,6 +14057,7 @@ process.$(OBJEXT): {$(VPATH)}onigmo.h
process.$(OBJEXT): {$(VPATH)}oniguruma.h
process.$(OBJEXT): {$(VPATH)}process.c
process.$(OBJEXT): {$(VPATH)}ractor.h
process.$(OBJEXT): {$(VPATH)}ractor_core.h
process.$(OBJEXT): {$(VPATH)}ruby_assert.h
process.$(OBJEXT): {$(VPATH)}ruby_atomic.h
process.$(OBJEXT): {$(VPATH)}rubyparser.h

View file

@ -114,6 +114,7 @@ int initgroups(const char *, rb_gid_t);
#include "ruby/st.h"
#include "ruby/thread.h"
#include "ruby/util.h"
#include "ractor_core.h"
#include "vm_core.h"
#include "vm_sync.h"
#include "ruby/ractor.h"
@ -4120,6 +4121,10 @@ rb_fork_async_signal_safe(int *status,
rb_pid_t
rb_fork_ruby(int *status)
{
if (UNLIKELY(!rb_ractor_main_p())) {
rb_raise(rb_eRactorIsolationError, "can not fork from non-main Ractors");
}
struct rb_process_status child = {.status = 0};
rb_pid_t pid;
int try_gc = 1, err = 0;

View file

@ -99,6 +99,17 @@ class TestRactor < Test::Unit::TestCase
RUBY
end
def test_fork_raise_isolation_error
assert_ractor(<<~'RUBY')
ractor = Ractor.new do
Process.fork
rescue Ractor::IsolationError => e
e
end
assert_equal Ractor::IsolationError, ractor.value.class
RUBY
end if Process.respond_to?(:fork)
def test_require_raises_and_no_ractor_belonging_issue
assert_ractor(<<~'RUBY')
require "tempfile"