Project

General

Profile

Actions

Bug #22468

open

A read of a class variable after remove_class_variable returns a broken value, then SEGV on use

Bug #22468: A read of a class variable after remove_class_variable returns a broken value, then SEGV on use

Added by hasumikin (hitoshi hasumi) about 12 hours ago. Updated about 12 hours ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [x86_64-linux]
[ruby-core:127223]

Description

Description

A method that read a class variable once reads it again after remove_class_variable. The second read does not raise NameError. It returns a broken value, and a use of that value causes a segmentation fault.

Steps to reproduce

class C
  @@x = 1
  def self.x
    @@x
  end
end
C.x
C.remove_class_variable(:@@x)
p C.x

Expected result

The second C.x raises NameError, as Ruby 2.7.8 does:

test.rb:4:in `x': uninitialized class variable @@x in C (NameError)
	from test.rb:9:in `<main>'

Actual result

test.rb:9: [BUG] Segmentation fault at 0x0000000000000034
ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [x86_64-linux]

The C level backtrace stops in flo_to_s (rb_float_noflonum_value, internal/numeric.h:287), which p calls through rb_inspect.

Notes

  • Without the first C.x (line 7), the second C.x raises NameError correctly. So the inline cache of the class variable read can keep the removed entry.

  • The read itself does not crash. p C.x.class prints Float, so the read returns a broken value with no error. The crash comes when the program uses the value.

  • With @@x = [] and GC.start before the second read, the crash is the same.

  • --yjit and --zjit give the same SEGV. With --yjit --yjit-call-threshold=1 or --zjit --zjit-call-threshold=1, p C.x prints main, and then Ruby stops with a different bug:

    main
    test.rb: [BUG] Stack consistency error (sp: 5, bp: -16598879043074)
    ruby 4.1.0dev (2026-10-24T08:43:21Z master e6403ebc10) +YJIT +PRISM [x86_64-linux]
    

Versions

Version Result
ruby 2.7.8 NameError (correct)
ruby 3.4.12 (2026-10-23 revision 366f5fdc00) SEGV
ruby 4.0.9 (2026-10-23 revision 3e93b23afc) SEGV
ruby 4.1.0dev (2026-10-24T08:43:21Z master e6403ebc10) SEGV

Platform: x86_64-linux (Ubuntu 24.04).

Updated by jeremyevans0 (Jeremy Evans) about 12 hours ago Actions #1 [ruby-core:127224]

In case it assists debugging, the example works correctly in Ruby 3.0 and 3.1 (NameError) and fails in Ruby 3.2 and 3.3 (SEGV). So it broke between Ruby 3.1 and 3.2.

Actions

Also available in: PDF Atom