Project

General

Profile

Actions

Bug #22411

closed

Assertion Failed: class_call_alloc_func:rb_obj_class(obj) == rb_class_real(klass)

Bug #22411: Assertion Failed: class_call_alloc_func:rb_obj_class(obj) == rb_class_real(klass)

Added by 0599jiangyc@gmail.com (Yuancheng Jiang) about 5 hours ago. Updated about 2 hours ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:126976]

Description

The following code:

class C < File::Stat; end
C.allocate

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:

ruby ./min.rb

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:

Ubuntu 24.04.4 LTS (x86_64), clang 18.1.3

This bug was found by fusion-fuzz

Updated by peterzhu2118 (Peter Zhu) about 3 hours ago Actions #1 [ruby-core:126978]

  • 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 Actions #2

  • 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:

class C < File::Stat; end
C.allocate

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
Actions

Also available in: PDF Atom