Skip to content

[Bug] GC death spiral causes process freeze with unresponsive Ctrl+C during long sessions #19344

Closed as not planned

Description

@itsgrimetime

Bug Description

Title: Claude Code freezes with high CPU, unresponsive to Ctrl+C/SIGTERM - GC death spiral

Description:
Claude Code occasionally freezes completely during long sessions. The process becomes unresponsive to all input including Ctrl+C and SIGTERM, requiring kill -9. This corrupts the terminal state and loses unsaved session context.

Symptoms:

  • Process uses 150-180% CPU but makes no progress
  • No response to keyboard input or signals
  • Only recoverable via SIGKILL

Diagnostic evidence:
Used sample 1 to capture stack trace. ~40% of samples were in V8 garbage collection:
287 v8::internal::Heap::CollectGarbage
287 v8::internal::Heap::Scavenge()
231 v8::platform::DefaultJobHandle::Join()
Memory footprint was 1.1GB (peak 1.4GB). Process was stuck in a GC death spiral - allocating faster than GC could reclaim.

Reproduction context:

  • Long-running session (~10+ minutes on a single task)
  • Working on decomp matching with large functions (1500+ bytes)
  • Froze during a large streaming response (status showed "34.0k tokens" during thinking)
  • Heavy use of subagents (Task tool) and iterative compilation

Frequency: Happening more often lately, multiple times in recent weeks.

Environment: macOS 15.5, Node 23.9.0, Apple Silicon


Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.12
  • Feedback ID: eac15baf-cbea-4464-a96e-440988c14f02

Errors

I opened a different session to gather the evidence, so anything attached from current session might not be directly relevant.

[{"error":"MaxFileReadTokenExceededError: File content (89996 tokens) exceeds maximum allowed tokens (25000). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.\n    at P62 (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1552:13647)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Object.call (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1561:996)\n    at async file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:4609:1551","timestamp":"2026-01-19T22:21:16.468Z"},{"error":"MaxFileReadTokenExceededError: File content (89996 tokens) exceeds maximum allowed tokens (25000). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.\n    at P62 (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1552:13647)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Object.call (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1561:996)\n    at async file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:4609:1551","timestamp":"2026-01-19T22:21:26.078Z"},{"error":"MaxFileReadTokenExceededError: File content (89996 tokens) exceeds maximum allowed tokens (25000). Please use offset and limit parameters to read specific portions of the file, or use the GrepTool to search for specific content.\n    at P62 (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1552:13647)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async Object.call (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:1561:996)\n    at async file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:4609:1551","timestamp":"2026-01-19T22:21:26.292Z"},{"error":"Error: Request was aborted.\n    at Jj.makeRequest (file:///opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js:934:3940)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)","timestamp":"2026-01-19T22:22:53.422Z"}]

Activity

  1. github-actions commented on Jan 19, 2026

    @github-actions

    Found 3 possible duplicate issues:

    1. [BUG] Claude Code v2.1.9 Complete Freeze - 100% CPU, Main Thread Stuck in Infinite Loop (macOS ARM64) #18532
    2. Memory leak causing V8 OOM crashes (SIGABRT) on extended sessions #18011
    3. [BUG] Memory leak in long-running idle Claude Code sessions #18859

    This issue will be automatically closed as a duplicate in 3 days.

    • If your issue is a duplicate, please close it and 👍 the existing issue instead
    • To prevent auto-closure, add a comment or 👎 this comment

    🤖 Generated with Claude Code

  2. ariccio commented on Jan 20, 2026

    @ariccio

    FWIW when you need to increase the heap size, this is the command I use: export NODE_OPTIONS="${NODE_OPTIONS:-} --max-old-space-size=16384

    I'm gonna spam this a few places since it's a useful workaround for some of the bugs in this claude code version where peak memory consumption may be 10x larger than average.

  3. raphaelweber commented on Jan 26, 2026

    @raphaelweber

    I'm experiencing similar freezes, but my analysis suggests a different root cause - not GC thrashing, but a thread deadlock.

    Thread State Analysis

    Analyzed a frozen process via /proc/<pid>/task/*/wchan:

    Thread Type State Count
    Main thread ep_poll (waiting for epoll events) 1
    Worker threads futex_wait_queue (blocked on mutex) 18
    I/O thread wait_woken 1

    Diagnosis

    This is not GC thrashing - the threads are blocked on mutexes, not in garbage collection.

    The main thread is stuck in ep_poll, waiting for events. The UI thread (which should process keyboard input) is blocked on futex_wait_queue - waiting for a mutex/lock.

    This indicates a classic deadlock:

    • One thread holds a lock and is waiting for I/O
    • The UI thread is waiting for the same lock
    • Result: Complete freeze, no input processing

    Key Difference from GC Death Spiral

    Metric GC Death Spiral (#19344) My Case
    CPU 150-180% Low (no spinning)
    Thread state GC functions futex_wait_queue
    Memory Growing Stable

    Additional Observations

    • Process shows State: R (running) because one thread is active, but the event loop never runs
    • Network connections to API server remain ESTABLISHED - TCP is open but no data flowing
    • Issue started a few days ago, occurs irregularly (every few minutes to hours)

    Concrete Reproduction Case

    I found a specific trigger: blocking serial port access.

    stty -F /dev/ttyUSB0 115200 raw -echo && timeout 8 cat /dev/ttyUSB0 2>&1 || true

    When Claude Code executes this via the Bash tool:

    • The process holds /dev/ttyUSB0 open (visible via lsof)
    • One thread is stuck on wait_woken (blocking read on serial port)
    • The entire UI freezes - even though timeout 8 should abort after 8 seconds
    • Esc doesn't work, timer stops, no input possible

    This suggests Bash tool execution blocks the main event loop instead of running asynchronously.

    Update: The freeze also occurs with non-blocking commands and even with background workarounds (command &). The issue is not specific to serial ports - any Bash tool execution can trigger the freeze. This happened multiple times within minutes during normal usage.

    Additional Evidence

    After killing the frozen process:

    • The terminal immediately showed buffered keystrokes that were typed during the freeze
    • These keystrokes were passed to the shell (causing "command not found" errors)
    • This confirms the UI thread was blocked but the process was still alive - keyboard input was buffered by the terminal but never read by Claude Code

    Environment

    • Claude Code 2.1.19
    • Ubuntu 24.04.3 LTS
    • Kernel 6.14.x

    This may be a separate issue or a different code path leading to similar symptoms. Wanted to document this in case it helps narrow down the problem.

  4. github-actions commented on Feb 28, 2026

    @github-actions

    Closing for now — inactive for too long. Please open a new issue if this is still relevant.

  5. github-actions commented on Mar 7, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  6. locked as resolved and limited conversation to collaborators on Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions