Project

General

Profile

Actions

Bug #22327

open

RubyVM::ZJIT.reset_stats! aborts the process (Rust panic) when ZJIT is not enabled

Bug #22327: RubyVM::ZJIT.reset_stats! aborts the process (Rust panic) when ZJIT is not enabled

Added by znz (Kazuhiro NISHIYAMA) 4 days ago.

Status:
Open
Assignee:
Target version:
-
ruby -v:
ruby 4.0.7 (2026-09-15 revision 229531a6cf) +PRISM [x86_64-linux]
[ruby-core:126747]

Description

RubyVM::ZJIT.reset_stats! aborts the whole process with a Rust panic when it is called while ZJIT is not enabled. The other stats methods (stats, stats_string, stats_enabled?) just return nil/false in the same situation, and RubyVM::YJIT.reset_stats! returns nil when YJIT is disabled, so I think reset_stats! should also be a no-op instead of crashing.

Reproduction

$ ruby -e 'p RubyVM::ZJIT.enabled?; RubyVM::ZJIT.reset_stats!; puts "after"'
false

thread '<unnamed>' (1) panicked at /usr/src/ruby/zjit/src/state.rs:200:13:
ZJITState::get_instance called when ZJIT is not enabled
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread '<unnamed>' (1) panicked at .../library/core/src/panicking.rs:225:5:
panic in a function that cannot unwind
(backtrace and bug report dump follow)
Aborted (core dumped)
$ echo $?
134

Expected: after is printed and the process exits with 0 (reset_stats! returns nil, as it does when ZJIT is enabled).

Reproduced with:

  • ruby 4.1.0dev (2026-09-15T06:59:41Z master 0c3c61ca82) +PRISM [x86_64-linux] (ghcr.io/ruby/ruby:master; panic at zjit/src/state.rs:200)
  • ruby 4.0.7 (2026-09-15 revision 229531a6cf) +PRISM [x86_64-linux] (ghcr.io/ruby/ruby:4.0.7; panic at zjit/src/state.rs:168)

For comparison, these do not crash:

$ ruby -e 'p RubyVM::ZJIT.stats, RubyVM::ZJIT.stats_string, RubyVM::ZJIT.stats_enabled?'
nil
nil
false
$ ruby -e 'p RubyVM::YJIT.enabled?, RubyVM::YJIT.reset_stats!'
false
nil
$ ruby --zjit -e 'p RubyVM::ZJIT.enabled?, RubyVM::ZJIT.reset_stats!'
true
nil

Cause

rb_zjit_reset_stats_bang in zjit/src/stats.rs calls ZJITState::get_counters() etc. unconditionally, and ZJITState::get_instance panics when the state has not been initialized. rb_zjit_stats in the same file starts with if !zjit_enabled_p() { return Qnil; }; adding the same guard to rb_zjit_reset_stats_bang would fix this.

🤖 Generated with Claude Code

No data to display

Actions

Also available in: PDF Atom