Cross-Engine GC Memory Corruption: V8 and JSC Crash Under Same Workload (83+ Dumps, 10 Signatures)

Resolved 💬 4 comments Opened Feb 22, 2026 by balandari Closed Mar 22, 2026

Cross-Engine GC Memory Corruption: V8 and JSC Crash Under Same Workload (83+ Dumps, 10 Signatures)

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

Summary

Claude Code crashes due to garbage collector memory corruption on both JavaScript engines it ships with:

  • Native (claude.exe): Bun 1.3.10 / JavaScriptCore -- 79+ crash dumps, 6 crash families (F1-F6)
  • npm (@anthropic-ai/claude-code): Node.js 24.13.1 / V8 -- 4 crash dumps, 4 distinct signatures

Two completely different GC implementations produce the same category of failure: use-after-free, stale pointer dereference, and heap corruption during normal operation. Upgrading Bun from 1.3.5 to 1.3.10 did not resolve the JSC crashes. The common denominator is the application workload, not the runtime.

This extends #21875 (our Bun crash investigation with 27 analyzed dumps) and #27356 (@jwhitehead-trafilea's cross-engine hypothesis) with new V8 crash dump evidence from cdb/WinDbg analysis.

---

Environment

| Component | Value |
|-----------|-------|
| OS | Windows 11 Pro x64 (Build 26200) |
| CPU | Intel i9-14900HX (32 logical, SSE4.2/AVX/AVX2) |
| RAM | 192 GB |
| Node.js | v24.13.1 (Active LTS, V8 13.6.233.17) |
| Bun | v1.3.10 (embedded in native Claude Code) |
| Claude Code | v2.1.x (native) / current (npm) |

---

Cross-Engine Crash Comparison

| Characteristic | Bun / JSC (native) | Node.js / V8 (npm) |
|---------------|-------------------|-------------------|
| Crash dumps analyzed | 27 (full cdb analysis) + 52 via crash reports | 4 (full cdb analysis) |
| Crash families | 6 (F1-F6) | 4 distinct signatures |
| Dominant exception | c0000005 (Access Violation) | c0000005 + c000001d (Illegal Instruction) |
| Pointer patterns | NaN-boxed sentinels (0xFFFE/0xFFFF prefix), near-null | Near-null, null+offset, 0xFFFFFFFF sentinel |
| GC mechanism | JSC MarkedBlock sweep UAF | V8 concurrent GC heap corruption |
| Detection | CPU fault (F2), Bun internal check (F4), heap manager (F6) | CPU fault (3 signatures), V8 self-detected (1 signature) |
| Process uptime at crash | 35 sec -- 73 min | 3 min 45 sec -- 5 min 2 sec |
| Thread at crash | Main thread | Main thread |
| Crash path | JIT code → napi_close_callback_scope → bmalloc/JSC | JIT code → uv_check_stop → MakeCallback → v8::Function::Call |
| Still crashing on latest? | Yes (Bun 1.3.10) | Yes (Node.js 24.13.1, latest v24) |

---

V8 Crash Dump Analysis (New Evidence)

Four node.exe crashes captured via ProcDump on Feb 21, 2026 within a 10-minute window. All on Node.js 24.13.1, separate process instances, main thread only.

| Dump | Uptime | Exception | Failure Bucket | Faulting Instruction |
|------|--------|-----------|----------------|---------------------|
| 211934 | -- | c0000005 | INVALID_POINTER_READ | Read from stale pointer (0xFFFFFFFF sentinel) |
| 212141 | -- | c0000005 | SOFTWARE_NX_FAULT | Executed non-executable memory (corrupted JIT code pointer) |
| 212534 | 5m02s | c0000005 | INVALID_POINTER_WRITE | mov qword ptr [rcx+10h], 0 with rcx=NULL |
| 212933 | 3m45s | c000001d | ILLEGAL_INSTRUCTION | ud2 at v8::base::OS::Abort (V8 self-detected corruption) |

Signature 1: INVALID_POINTER_WRITE (dump 212534)
ExceptionAddress: 00007ff766628660 (node!v8::platform::DelayedTaskQueue::Terminate+0x7c380)
   ExceptionCode: c0000005 (Access violation)
   Parameter[0]: 0000000000000001
   Parameter[1]: 0000000000000010
Attempt to write to address 0000000000000010

CONTEXT:
  rcx=0000000000000000  rdx=0000000000000000
  rip=00007ff766628660  rsp=0000005ca5bfac68

STACK (key frames):
  node!v8::platform::DelayedTaskQueue::Terminate+0x7c380   ← crash (rcx=NULL)
  node!v8::base::debug::StackTrace::ToString+0x18c257
  node!v8::RegExp::GetFlags+0x8d6f3
  node!X509_STORE_set_get_issuer+0x7c08e                   ← V8 internal (symbol noise)
  0x00000193be67727a                                        ← JIT code
  [... deep recursive JIT frames ...]
  node!v8::Function::Call+0x46
  node!node::MakeCallback+0x5e
  node!uv_check_stop+0xde                                   ← libuv check callback
  node!uv_run+0x340                                         ← event loop

V8 attempted to write to offset 0x10 of an object, but the object pointer (rcx) was null. The object was freed by GC while JIT code still held a reference. Deep recursive JIT call stack with 9+ repeated frames at 0x0000020c38f770b8 indicates heavy JavaScript execution at crash time.

Signature 2: V8 Deliberate Abort (dump 212933)
ExceptionAddress: 00007ff7662c2dd3 (node!v8::base::OS::Abort+0x63)
   ExceptionCode: c000001d (Illegal instruction)
Faulting instruction: ud2

STACK (key frames):
  node!v8::base::OS::Abort+0x63                             ← deliberate ud2
  node!v8::base::CPU::has_sse41+0x8463                      ← V8 internal (symbol noise)
  node!v8::RegExp::GetFlags+0x3aa33
  node!v8::WasmStreaming::Unpack+0xd479
  node!v8::Platform::SystemClockTimeMillis+0x3028f
  0x000001dd9fe7733a                                        ← JIT code
  [... deep recursive JIT frames with alternating patterns ...]
  node!v8::Function::Call+0x46
  node!node::MakeCallback+0x5e
  node!uv_check_stop+0xde
  node!uv_run+0x340

V8 detected its own heap corruption and deliberately crashed via ud2 (undefined instruction) in OS::Abort. This is V8's self-defense mechanism -- it found inconsistent heap state during verification and aborted rather than continuing with corrupt data.

Common V8 Crash Pattern

All four V8 dumps share:

  1. Entry path: uv_runuv_check_stopnode::MakeCallbackv8::Function::Call → JIT code
  2. Main thread only -- all background threads (V8 workers, libuv workers, delayed task scheduler) idle at crash time
  3. Deep recursive JIT call stacks -- heavy JavaScript execution with repeated frame patterns
  4. Short-lived processes (3-5 min) -- corruption manifests quickly under workload

The four signatures are four symptoms of one underlying problem: V8's GC corrupts live object references under this workload. Which symptom appears depends on which corrupted pointer V8 touches first:

| Symptom | What V8 Did |
|---------|-------------|
| Read stale sentinel | Dereferenced freed object → read poisoned memory |
| Execute heap data | Followed corrupted code pointer into data region |
| Write through null | Object pointer freed/zeroed → null deref at field offset |
| Deliberate abort | V8's own verification caught inconsistency |

---

JSC Crash Families (Established Evidence)

From #21875 -- 27 full memory dumps analyzed via cdb, classified into 6 families:

| Family | Exception | Frequency | Mechanism |
|--------|-----------|-----------|-----------|
| F2: JSC GC UAF | c0000005 | 81.5% | NaN-boxed tagged pointer dereference after GC freed object |
| F4: FAST_FAIL | c0000409 | 11.1% | Bun internal corruption check → __fastfail(7) |
| F5: Partial Pointer | c0000005 | 3.7% | Corrupted pointer with valid prefix, garbage suffix |
| F6: Heap Double-Free | c0000374 | 3.7% | Windows heap manager detects LFH double-free |
| F1: Worker Thread | c0000005 | Rare | Worker thread cleanup UAF |
| F3: Heap Address | c0000005 | Variable | Freed heap memory dereference |

All families trace through napi_close_callback_scope in Bun's N-API implementation. F4 stack traces show 3 frames through this function before the abort. F6 confirms the mechanism: napi_close_callback_scopepas_system_heap_freeRtlFreeHeapHEAP_FAILURE_SEGMENT_LFH_DOUBLE_FREE.

Bun 1.3.10 still produces these crashes. The Bun 1.3.7 JSC upgrade did not resolve the underlying issue.

---

V8 CVE Context

Node.js 24.13.1 ships V8 13.6.233.17 (Chrome 136 vintage). Three CVEs fixed in later Chrome versions pattern-match our V8 crash signatures:

| CVE | Description | Fixed In | Matching Signature |
|-----|-------------|----------|--------------------|
| CVE-2025-6558 | JIT compilation race condition causing memory corruption | Chrome 137 | SOFTWARE_NX_FAULT (corrupted JIT pointer) |
| CVE-2025-9864 | Use-after-free in V8, heap corruption | Chrome 140 | INVALID_POINTER_READ (stale sentinel) |
| CVE-2025-13042 | Inappropriate implementation leading to heap corruption | Chrome 142 | General heap corruption |

These CVEs have not been cherry-picked to Node.js 24's V8 branch. Node.js 24.13.1 is the latest v24 release.

These CVEs may contribute to the V8-side crashes, but they do not explain the JSC-side crashes. The cross-engine nature of the problem points to the application workload as the primary factor.

---

Reproduction

Non-deterministic. Crashes typically occur within 1-10 minutes of sustained use.

  1. Run Claude Code (native or npm) on Windows x64
  2. Use normally -- tool calls, subprocess spawning, multi-agent orchestration
  3. Process crashes between 35 seconds and 73 minutes

Higher subprocess spawn volume widens the race window. Our workflow involves multi-agent orchestration (hundreds of spawns per session). Other users report crashes at lower activity levels (#27320, #26984).

---

The Question

Two independent GC implementations (JSC and V8) both corrupt memory under Claude Code's workload. The runtimes have no shared GC code. The shared factors are:

  • Heavy async subprocess spawning (child_process.spawn / equivalent)
  • Deep callback nesting across async boundaries
  • Rapid object allocation and deallocation during tool call processing
  • N-API native addon lifecycle operations during active GC

What in Claude Code's workload is generating this GC pressure? Specifically:

  1. Is there instrumentation that can profile the allocation rate and object churn during tool call processing?
  2. Are there N-API cleanup operations that could be deferred or batched to reduce GC contention?
  3. Has this crash pattern been observed in Anthropic's internal testing on Windows?

Full ProcDump captures (.dmp files) are available for all 83+ crashes if the engineering team wants them for analysis.

Related Issues

  • #21875 -- Our original Bun crash investigation (78 crashes, 27 analyzed dumps, F1-F6 classification)
  • #27356 -- @jwhitehead-trafilea's cross-engine hypothesis (N-API addon lifecycle)
  • #27320 -- Bun 1.3.10 still crashing with same signature
  • #26984 -- Bun 1.3.10 crash after 2h session
  • oven-sh/bun#27003 -- Our Bun-side root cause report (N-API cleanup race condition)

Claude Code Version

2.1.50+ (npm), latest native

Platform

Anthropic API (Claude Max)

Operating System

Windows 11 Pro x64 (Build 26200)

Note

This issue was written by Claude (Opus 4.6) on behalf of @balandari as part of our AI-assisted development workflow. Full ProcDump captures (.dmp files, 83+ crashes totaling ~113 GB) are available on request.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗