Bug #21716
openYJIT panic: "all PendingBranchRefs should be unique" in net/http response reading (infinite unwind loop)
Description
We encountered a YJIT panic in production that caused the process to enter an infinite logging loop for several hours. The panic occurs within yjit/src/core.rs when handling branch references.
The trigger appears to be in net/http, specifically when reading a response body (possibly involving chunked encoding or zlib) inside a Datadog trace transport flush.
Key Observations:
The Panic: YJIT fails with all PendingBranchRefs should be unique when ready to construct a Block.
The Loop: After the panic, the process fails to exit and instead logs rust_begin_unwind and try_fold iterator errors repeatedly, filling logs for hours.
System Configuration
Ruby Version: ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [aarch64-linux]
Environment: Linux aarch64 (AWS Graviton/ARM)
Reproduction Context
While we cannot provide a standalone reproduction script yet, the crash happens intermittently during a Net::HTTP request initiated by datadog-ruby (v2.17.0) to flush traces to a Unix socket, which is wrapped by sentry-ruby (v5.26.0).
Ruby Location: /gems/net-http-0.6.0/lib/net/http/response.rb:604
Rust Location: ./yjit/src/core.rs:2403:27
Backtrace & Logs
ruby: YJIT has panicked. More info to follow...
thread '<unnamed>' panicked at 'all PendingBranchRefs should be unique when ready to construct a Block', ./yjit/src/core.rs:2403:27
stack backtrace:
0: rust_begin_unwind
at /rustc/.../library/std/src/panicking.rs:578:5
...
28: yjit::core::branch_stub_hit
at /workspace/ruby-3.4.7/yjit/src/core.rs:3492:9
/gems/net-http-0.6.0/lib/net/http/response.rb:604: [BUG] YJIT: panicked at 'all PendingBranchRefs should be unique when ready to construct a Block', ./yjit/src/core.rs:2403:27
-- Control frame information -----------------------------------------------
c:0047 p:0049 s:0248 e:000247 BLOCK /gems/net-http-0.6.0/lib/net/http/response.rb:604
c:0046 p:0098 s:0243 e:000242 METHOD /gems/net-http-0.6.0/lib/net/http/response.rb:588
c:0045 p:0004 s:0235 e:000234 METHOD /gems/net-http-0.6.0/lib/net/http/response.rb:593
...
c:0039 p:0033 s:0196 e:000195 BLOCK /gems/sentry-ruby-5.26.0/lib/sentry/net/http.rb:44
...
c:0033 p:0023 s:0158 e:000157 METHOD /gems/datadog-2.17.0/lib/datadog/core/transport/http/adapters/unix_socket.rb:43
c:0032 p:0066 s:0152 e:000151 METHOD /gems/datadog-2.17.0/lib/datadog/core/transport/http/adapters/net.rb:77
The stack suggests the crash happens during branch_stub_hit resolution. The presence of sentry-ruby and datadog suggests complex interaction with Net::HTTP patching.
The infinite loop of logs following the crash looks like this (repeated):
/usr/lib/libruby.so.3.4(try_fold<alloc::vec::into_iter::IntoIter<alloc::rc::Rc<yjit::core::PendingBranch> ...
This suggests the panic handler itself is tripping over the corrupted PendingBranch state. We encountered a YJIT panic in production that caused the process to enter an infinite logging loop for several hours. The panic occurs within yjit/src/core.rs when handling branch references.
The trigger appears to be in net/http, specifically when reading a response body (possibly involving chunked encoding or zlib) inside a Datadog trace transport flush.
Updated by ivoanjo (Ivo Anjo) about 13 hours ago
👋 I'll add that we have some limited crash telemetry at Datadog and I've seen what might be the same issue (YJIT failing somewhere inside branch_stub_hit) on both Ruby 3.3 and 3.4 (maybe 3.2 but unclear? if the same) on both x86-64 and arm64.
If it helps, I can provide some of the native stack traces we're seeing.
Updated by alanwu (Alan Wu) about 5 hours ago
- Description updated (diff)
There is two separate issues here, YJIT panicking, and the crash reporter looping during stack tracing. During development, I've seen the the crash reporter go into infinite loop on aarch64-dwarin, too.
The rust unwinder seems to be working fine, and the infinite loop seems to be from ruby's own DWARF parser and unwinder in addr2line.c. Can you confirm that before the repeated stack trace lines there is a line that says "C level backtrace information"?