Project

General

Profile

Actions

Bug #21772

closed

ruby: YJIT has panicked StackOpnd(1) should be a heap object, but was ImmSymbol for VALUE(137647867319760)

Bug #21772: ruby: YJIT has panicked StackOpnd(1) should be a heap object, but was ImmSymbol for VALUE(137647867319760)

Added by gearoiddc (Gearoid de Cleir) 2 days ago. Updated about 7 hours ago.

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

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

session_blocks.log (356 KB) session_blocks.log gearoiddc (Gearoid de Cleir), 12/11/2025 03:29 PM

Updated by gearoiddc (Gearoid de Cleir) 2 days ago Actions #1

  • Description updated (diff)

Updated by k0kubun (Takashi Kokubun) 2 days ago Actions #2 [ruby-core:124123]

  • Assignee set to jit

Backtrace & Logs

Is it possible to share the Ruby backtrace as well?

Updated by gearoiddc (Gearoid de Cleir) 2 days ago Actions #3 [ruby-core:124124]

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) 1 day ago Actions #4 [ruby-core:124144]

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) 1 day ago 1Actions #5 [ruby-core:124145]

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 10 hours ago Actions #6

  • 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 7 hours ago Actions #7 [ruby-core:124176]

  • 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

Actions

Also available in: PDF Atom