Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/rubyPublic

Commit8bf333a

Browse files
committed
Fix live object count for multi-Ractor forking
Since we do not run a Ractor barrier before forking, it's possible thatanother other Ractor is halfway through allocating an object during forking.This may lead to allocated_objects_count being off by one.For example, the following script reproduces the bug: 100.times do |i| Ractor.new(i) do |j| 10000.times do |i| "#{j}-#{i}" end Ractor.receive end pid = fork { GC.verify_internal_consistency } _, status = Process.waitpid2 pid raise unless status.success? endWe need to run with `taskset -c 1` to force it to use a single CPU coreto more consistenly reproduce the bug: heap_pages_final_slots: 1, total_freed_objects: 16628 test.rb:8: [BUG] inconsistent live slot number: expect 19589, but 19588. ruby 4.0.0dev (2025-11-25T03:06:55Z master55892f5) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0007 p:---- s:0029 e:000028 l:y b:---- CFUNC :verify_internal_consistency c:0006 p:0004 s:0025 e:000024 l:n b:---- BLOCK test.rb:8 [FINISH] c:0005 p:---- s:0022 e:000021 l:y b:---- CFUNC :fork c:0004 p:0012 s:0018 E:0014c0 l:n b:---- BLOCK test.rb:8 c:0003 p:0024 s:0011 e:000010 l:y b:0001 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 E:001730 l:n b:---- EVAL test.rb:1 [FINISH] c:0001 p:0000 s:0003 E:001d20 l:y b:---- DUMMY [FINISH] -- Ruby level backtrace information ---------------------------------------- test.rb:1:in '<main>' <internal:numeric>:257:in 'times' test.rb:8:in 'block in <main>' test.rb:8:in 'fork' test.rb:8:in 'block (2 levels) in <main>' test.rb:8:in 'verify_internal_consistency' -- Threading information --------------------------------------------------- Total ractor count: 1 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- ruby(rb_print_backtrace+0x14) [0x61b67ac48b60] vm_dump.c:1105 ruby(rb_vm_bugreport) vm_dump.c:1450 ruby(rb_bug_without_die_internal+0x5f) [0x61b67a818a28] error.c:1098 ruby(rb_bug) error.c:1116 ruby(gc_verify_internal_consistency_+0xbdd) [0x61b67a83d8ed] gc/default/default.c:5186 ruby(gc_verify_internal_consistency+0x2d) [0x61b67a83d960] gc/default/default.c:5241 ruby(rb_gc_verify_internal_consistency) gc/default/default.c:8950 ruby(gc_verify_internal_consistency_m) gc/default/default.c:8966 ruby(vm_call_cfunc_with_frame_+0x10d) [0x61b67a9e50fd] vm_insnhelper.c:3902 ruby(vm_sendish+0x111) [0x61b67a9eeaf1] vm_insnhelper.c:6124 ruby(vm_exec_core+0x84) [0x61b67aa07434] insns.def:903 ruby(vm_exec_loop+0xa) [0x61b67a9f8155] vm.c:2811 ruby(rb_vm_exec) vm.c:2787 ruby(vm_yield_with_cref+0x90) [0x61b67a9fd2ea] vm.c:1865 ruby(vm_yield) vm.c:1873 ruby(rb_yield) vm_eval.c:1362 ruby(rb_protect+0xef) [0x61b67a81fe6f] eval.c:1154 ruby(rb_f_fork+0x16) [0x61b67a8e98ab] process.c:4293 ruby(rb_f_fork) process.c:4284
1 parent4263f1d commit8bf333a

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

‎bootstraptest/test_ractor.rb‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2370,3 +2370,24 @@ def call_test(obj)
23702370
:ok
23712371
end
23722372
RUBY
2373+
2374+
assert_equal'ok',<<~'RUBY'
2375+
begin
2376+
100.times do |i|
2377+
Ractor.new(i) do |j|
2378+
1000.times do |i|
2379+
"#{j}-#{i}"
2380+
end
2381+
end
2382+
pid = fork do
2383+
GC.verify_internal_consistency
2384+
end
2385+
_, status = Process.waitpid2 pid
2386+
raise unless status.success?
2387+
end
2388+
2389+
:ok
2390+
rescue NotImplementedError
2391+
:ok
2392+
end
2393+
RUBY

‎gc/default/default.c‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,8 @@ typedef struct rb_objspace {
622622
rb_postponed_job_handle_tfinalize_deferred_pjob;
623623

624624
unsigned longlive_ractor_cache_count;
625+
626+
intfork_vm_lock_lev;
625627
}rb_objspace_t;
626628

627629
#ifndefHEAP_PAGE_ALIGN_LOG
@@ -9324,12 +9326,20 @@ gc_malloc_allocations(VALUE self)
93249326
void
93259327
rb_gc_impl_before_fork(void*objspace_ptr)
93269328
{
9327-
/* no-op */
9329+
rb_objspace_t*objspace=objspace_ptr;
9330+
9331+
objspace->fork_vm_lock_lev=RB_GC_VM_LOCK();
9332+
rb_gc_vm_barrier();
93289333
}
93299334

93309335
void
93319336
rb_gc_impl_after_fork(void*objspace_ptr,rb_pid_tpid)
93329337
{
9338+
rb_objspace_t*objspace=objspace_ptr;
9339+
9340+
RB_GC_VM_UNLOCK(objspace->fork_vm_lock_lev);
9341+
objspace->fork_vm_lock_lev=0;
9342+
93339343
if (pid==0) {/* child process */
93349344
rb_gc_ractor_newobj_cache_foreach(gc_ractor_newobj_cache_clear,NULL);
93359345
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp