Bug #22411
closedAssertion Failed: class_call_alloc_func:rb_obj_class(obj) == rb_class_real(klass)
Description
The following code:
Resulted in this output (RUBY_DEBUG build):
../object.c:2310: Assertion Failed: class_call_alloc_func:rb_obj_class(obj) == rb_class_real(klass)
ruby 4.1.0dev (2026-10-07) +PRISM [x86_64-linux]
-- Ruby level backtrace information ----------------------------------------
stat_min.rb:2:in '<main>'
stat_min.rb:2:in 'allocate'
-- C level backtrace information -------------------------------------------
(rb_assert_failure_detail+0x233) error.c:1268
(rb_assert_failure) (null):0
(RCLASS_INITIALIZED_P+0x0) object.c:2310
(class_get_alloc_func) object.c:2279
(rb_class_alloc) object.c:2270
(vm_call_cfunc_with_frame_+0x27b) ../vm_insnhelper.c:3906
(vm_call_method_each_type+0x24a) ../vm_insnhelper.c:4898
(vm_exec_core+0x113bc) ../vm_insnhelper.c:6285
(rb_vm_exec+0x242) vm.c:2909
On a non-debug build there is no crash, but the behaviour is wrong (regression; v3_4_0 source still passed klass):
class C < File::Stat; end
p C.allocate.class # ruby 3.2.3: C master: File::Stat
class D < File::Stat; def initialize(*) = (@x = 1); end
d = D.new("/")
p d.class, d.instance_variable_get(:@x) # 3.2: D, 1 master: File::Stat, nil (D#initialize is never called)
rb_stat_s_alloc(VALUE klass) calls stat_alloc(rb_cStat, &obj) instead of stat_alloc(klass, &obj).
This appears to have been introduced by 18a036a613 ("[Feature #21205] Define File::Stat#birthtime by statx");
before it the allocator was stat_new_0(klass, 0). Present in v4.0.7 and current master.
To reproduce:
Commit:
3296d5c99ce005e4698fb27a405e01d766ad2647 (2026-09-15); also reproduced on master 9ce0df671980d669cbab8afc48124c7453897533 (2026-10-07)
Build configuration:
../configure --disable-install-doc CC=clang-18 cflags="-fsanitize=address -fno-omit-frame-pointer -DUSE_MN_THREADS=0" cppflags="-DRUBY_DEBUG=1" optflags="-O1" debugflags="-g"
Operating System:
This bug was found by fusion-fuzz
Updated by peterzhu2118 (Peter Zhu) about 3 hours ago
- Backport changed from 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN to 3.3: DONTNEED, 3.4: DONTNEED, 4.0: DONTNEED
Thank you for the bug report. I have a fix here: https://github.com/ruby/ruby/pull/19249
Updated by peterzhu2118 (Peter Zhu) about 2 hours ago
- Status changed from Open to Closed
Applied in changeset git|05fc8ad175b68c8521015df1905f46be5ef1f967.
Fix incorrect class of File::Stat subclass instance
[Bug #22411]
rb_stat_s_alloc should use the class of the object and not assume it is
File::Stat.
The following script crashes when assertions are enabled:
With the following error:
object.c:2310: Assertion Failed: class_call_alloc_func:rb_obj_class(obj) == rb_class_real(klass)
ruby 4.1.0dev (2026-10-07T07:57:31Z master 9ce0df6719) +PRISM [arm64-darwin27]
-- Crash Report log information --------------------------------------------
See Crash Report log file in one of the following locations:
* ~/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:0003 p:---- s:0010 e:000009 l:y b:0001 r:0x0 CFUNC :allocate
c:0002 p:0013 s:0006 e:000005 l:n b:---- r:0x0 EVAL test.rb:2 [FINISH]
c:0001 p:0000 s:0003 E:0000a8 l:y b:---- r:0x0 DUMMY [FINISH]
-- Ruby level backtrace information ----------------------------------------
test.rb:2:in '<main>'
test.rb:2:in 'allocate'
-- Threading information ---------------------------------------------------
Total ractor count: 1
Ruby thread count for this ractor: 1
-- C level backtrace information -------------------------------------------
miniruby(rb_assert_failure_detail+0xf0) [0x104d12fe4] error.c:1268
miniruby(rb_assert_failure_detail) (null):0
miniruby(rb_assert_failure_detail+0x0) [0x104d12ef4] error.c:1244
miniruby(rb_assert_failure) (null):0
miniruby(class_call_alloc_func+0x20) [0x104d18568] object.c:2310
miniruby(rb_class_alloc.cold.3) object.c:2271
miniruby(rb_class_alloc.cold.6) (null):0
miniruby(rb_class_alloc+0xf0) [0x104912288] object.c:2310
miniruby(vm_call_cfunc_with_frame_+0xe8) [0x104a877b8] vm_insnhelper.c:3906
miniruby(vm_exec_core+0x42ec) [0x104a61d48] vm_insnhelper.c:6285
miniruby(vm_exec_loop+0x0) [0x104a5b240] vm.c:2909
miniruby(rb_vm_exec) vm.c:2912
miniruby(rb_ec_exec_node+0xa0) [0x104868450] eval.c:300
miniruby(ruby_run_node+0x64) [0x104868354] eval.c:338
miniruby(rb_main+0x1c) [0x10479c9b0] main.c:42
miniruby(main) main.c:62