Bug #22468
openA read of a class variable after remove_class_variable returns a broken value, then SEGV on use
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¶
Expected result¶
The second C.x raises NameError, as Ruby 2.7.8 does:
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 secondC.xraises 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.classprintsFloat, so the read returns a broken value with no error. The crash comes when the program uses the value. -
With
@@x = []andGC.startbefore the second read, the crash is the same. -
--yjitand--zjitgive the same SEGV. With--yjit --yjit-call-threshold=1or--zjit --zjit-call-threshold=1,p C.xprintsmain, and then Ruby stops with a different bug:
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).