Bug #21772
closedruby: YJIT has panicked StackOpnd(1) should be a heap object, but was ImmSymbol for VALUE(137647867319760)
Description
I'm getting a YJIT has panicked crash in my rails app locally when a part of my application rapidly uses a gem I have "auto_session_timeout".
If I patch the gem by changing the symbol to a string the error goes away.
module AutoSessionTimeout
private
def session_expired?(c)
c.session[:auto_session_expires_at].<(Time.now)
end
end
to
def session_expired?(c)
c.session["auto_session_expires_at"].<(Time.now)
end
I can consistently cause the crash but I can't find a way to reproduce the error in a snipped of code.
But it looks like YJIT is keeping the key as a sybmol even though it was converted to a string.
def [](key)
load_for_read!
key = key.to_s
if key == "session_id" # <-- crash occurs here
id&.public_id
else
@delegate[key]
end
end
Didn't have the same issue on ruby 3.3 with YJIT.
System Configuration
Ruby Version: ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Environment: Ubuntu 22.04.5 LTS (x86_64)
Backtrace & Logs
ruby: YJIT has panicked. More info to follow...
thread '<unnamed>' panicked at ./yjit/src/codegen.rs:5018:9:
StackOpnd(1) should be a heap object, but was ImmSymbol for VALUE(137647867319760)
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panicking.rs:697:5
1: core::panicking::panic_fmt
at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/core/src/panicking.rs:75:14
2: yjit::codegen::jit_guard_known_klass
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/codegen.rs:5018:9
3: yjit::codegen::gen_equality_specialized
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/codegen.rs:3690:9
4: yjit::codegen::gen_opt_eq
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/codegen.rs:3753:29
5: yjit::codegen::gen_single_block
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/codegen.rs:1382:22
6: yjit::core::gen_block_series_body
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3088:23
7: yjit::core::gen_block_series
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3066:18
8: yjit::core::branch_stub_hit_body
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3604:17
9: yjit::core::branch_stub_hit::{{closure}}::{{closure}}
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3493:36
10: yjit::stats::with_compile_time
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/stats.rs:1084:15
11: yjit::core::branch_stub_hit::{{closure}}
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3493:13
12: std::panicking::catch_unwind::do_call
at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panicking.rs:589:40
13: std::panicking::catch_unwind
at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panicking.rs:552:19
14: std::panic::catch_unwind
at /rustc/1159e78c4747b02ef996e55082b704c09b970588/library/std/src/panic.rs:359:14
15: yjit::cruby::with_vm_lock
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/cruby.rs:688:21
16: yjit::core::branch_stub_hit
at /home/travis/.rvm/src/ruby-3.4.7/yjit/src/core.rs:3492:9
17: <unknown>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/request/session.rb:118: [BUG] YJIT: panicked at ./yjit/src/codegen.rs:5018:9:
StackOpnd(1) should be a heap object, but was ImmSymbol for VALUE(137647867319760)
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]
Files
Updated by gearoiddc (Gearoid de Cleir) 3 days ago
- Description updated (diff)
Updated by k0kubun (Takashi Kokubun) 3 days ago
- Assignee set to jit
Backtrace & Logs
Is it possible to share the Ruby backtrace as well?
Updated by gearoiddc (Gearoid de Cleir) 3 days ago
Sure no problem anything else?
-- Ruby level backtrace information ----------------------------------------
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/thread_pool.rb:182:in 'block in spawn_thread'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/server.rb:262:in 'block in run'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/server.rb:503:in 'process_client'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/request.rb:100:in 'handle_request'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/thread_pool.rb:355:in 'with_force_shutdown'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/request.rb:101:in 'block in handle_request'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/puma-7.1.0/lib/puma/configuration.rb:300:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/railties-7.2.3/lib/rails/engine.rb:535:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-mini-profiler-3.0.0/lib/mini_profiler/profiler.rb:393:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/host_authorization.rb:143:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/sendfile.rb:127:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/static.rb:27:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/executor.rb:16:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/server_timing.rb:60:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/server_timing.rb:26:in 'collect_events'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/server_timing.rb:61:in 'block in call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/runtime.rb:22:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/method_override.rb:24:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/request_id.rb:33:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/request_store-1.5.1/lib/request_store/middleware.rb:19:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/remote_ip.rb:96:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/sprockets-rails-3.5.1/lib/sprockets/rails/quiet_assets.rb:17:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/railties-7.2.3/lib/rails/rack/logger.rb:29:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/railties-7.2.3/lib/rails/rack/logger.rb:41:in 'call_app'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/show_exceptions.rb:32:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:31:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/airbrake-13.0.5/lib/airbrake/rack/middleware.rb:23:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/airbrake-13.0.5/lib/airbrake/rack/middleware.rb:34:in 'call!'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/better_errors-2.9.1/lib/better_errors/middleware.rb:60:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/better_errors-2.9.1/lib/better_errors/middleware.rb:82:in 'better_errors_call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/better_errors-2.9.1/lib/better_errors/middleware.rb:87:in 'protected_app_call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/actionable_exceptions.rb:18:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/executor.rb:16:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/callbacks.rb:30:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:101:in 'run_callbacks'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/callbacks.rb:31:in 'block in call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activerecord-7.2.3/lib/active_record/migration.rb:674:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/middleware/cookies.rb:704:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/session/abstract/id.rb:260:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/session/abstract/id.rb:266:in 'context'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/http/content_security_policy.rb:38:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/http/permissions_policy.rb:38:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/head.rb:12:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/conditional_get.rb:27:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/etag.rb:27:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-2.2.21/lib/rack/tempfile_reaper.rb:15:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/warden-1.2.9/lib/warden/manager.rb:34:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/warden-1.2.9/lib/warden/manager.rb:34:in 'catch'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/warden-1.2.9/lib/warden/manager.rb:36:in 'block in call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/remotipart-1.4.4/lib/remotipart/middleware.rb:32:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/rack-attack-6.6.1/lib/rack/attack.rb:127:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/bullet-8.0.8/lib/bullet/rack.rb:21:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/scout_apm-5.7.0/lib/scout_apm/middleware.rb:17:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/scout_apm-5.7.0/lib/scout_apm/instant/middleware.rb:55:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:169:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/omniauth-1.9.2/lib/omniauth/strategy.rb:192:in 'call!'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/routing/route_set.rb:896:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/journey/router.rb:34:in 'serve'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/journey/router.rb:126:in 'find_routes'
<internal:array>:228:in 'each'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/journey/router.rb:133:in 'block in find_routes'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/journey/router.rb:53:in 'block in serve'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/routing/route_set.rb:50:in 'serve'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/routing/route_set.rb:67:in 'dispatch'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal.rb:335:in 'dispatch'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal.rb:252:in 'dispatch'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionview-7.2.3/lib/action_view/rendering.rb:40:in 'process'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/abstract_controller/base.rb:152:in 'process'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activerecord-7.2.3/lib/active_record/railties/controller_runtime.rb:39:in 'process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal/params_wrapper.rb:259:in 'process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal/instrumentation.rb:76:in 'process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/notifications.rb:210:in 'instrument'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/notifications/instrumenter.rb:58:in 'instrument'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/notifications.rb:210:in 'block in instrument'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal/instrumentation.rb:77:in 'block in process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_controller/metal/rescue.rb:27:in 'process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/abstract_controller/callbacks.rb:260:in 'process_action'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:109:in 'run_callbacks'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:560:in 'invoke_before'
<internal:array>:228:in 'each'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:560:in 'block in invoke_before'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:180:in 'call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/abstract_controller/callbacks.rb:34:in 'block (2 levels) in <module:Callbacks>'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:179:in 'block in call'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:429:in 'block in make_lambda'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/activesupport-7.2.3/lib/active_support/callbacks.rb:429:in 'instance_exec'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/auto-session-timeout-1.3/lib/auto_session_timeout.rb:10:in 'block in auto_session_timeout'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/auto-session-timeout-1.3/lib/auto_session_timeout.rb:48:in 'session_expired?'
/home/gearoid/.rvm/gems/ruby-3.4.7@7.2.3/gems/actionpack-7.2.3/lib/action_dispatch/request/session.rb:118:in '[]'
Updated by alanwu (Alan Wu) 2 days ago
It looks like you've hit the same panic as #21565.
Could you try the instructions from https://bugs.ruby-lang.org/issues/21565#note-5 to gather more information? Since you're on 3.4.7, you don't need to patch ruby for the steps there.
Updated by gearoiddc (Gearoid de Cleir) 2 days ago
- File session_blocks.log session_blocks.log added
I've attached a file the original log file was 90mb so I used
grep -B 2 -A 100 "action_dispatch/request/session.rb" /tmp/yjit_58847.log > /tmp/session_blocks.log
Hopefully that is what you are looking for.
Updated by alanwu (Alan Wu) about 18 hours ago
- Status changed from Open to Closed
Applied in changeset git|2884f53519c4b86072d5fc3b41a71cee697af8ba.
YJIT: Add missing local variable type update for fallback setlocal blocks
Previously, the chain_depth>0 version of setlocal blocks did not
update the type of the local variable in the context. This can leave
the context with stale type information and trigger panics like in
[Bug #21772] or lead to miscompilation.
To trigger the issue, YJIT needs to see the same ISEQ before and after
environment escape and have tracked type info before the escape. To
trigger in ISEQs that do not send with a block, it probably requires
Kernel#binding or the use of include/ruby/debug.h APIs.
Updated by alanwu (Alan Wu) about 16 hours ago
- Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED
Thanks for sharing the logs -- I was able to track down the issue using it.
Backport for 3.4 is pending at https://github.com/ruby/ruby/pull/15535