Skip to content

grep subprocesses leak memory catastrophically, causing macOS kernel panic #897

Description

@javiersantaella-coder

Summary

RTK spawns grep subprocesses (via rtk grep rewrites) that accumulate memory without releasing it. On a 96GB Mac
Studio M2 Ultra, 8 concurrent grep processes in RTK's coalition consumed a combined ~514GB (RAM + swap), exhausting
all memory and triggering a macOS kernel panic.

Environment

  • RTK version: 0.29.0
  • macOS: 26.3.1 (25D2128), Apple Silicon (Mac15,14 / M2 Ultra)
  • RAM: 96GB
  • Integration: Claude Code PreToolUse hook via rtk-rewrite.sh

What happened

While Claude Code was running bash commands (all routed through the RTK hook), grep subprocesses spawned by RTK
accumulated memory progressively over the session. The system triggered 5 JetsamEvents between 09:48–10:03 UTC
before crashing.

Kernel panic log:
panic(cpu 3 caller 0xfffffe0038d680e4): userspace watchdog timeout:
no successful checkins from WindowServer in 204 seconds

WindowServer could not allocate memory and hung, causing a hard reboot.

Data from JetsamEvent at crash time (coalition 707 = RTK)

┌─────────┬───────────┬───────────────────────────┐
│ Process │ Instances │ Total memory (incl. swap) │
├─────────┼───────────┼───────────────────────────┤
│ grep │ 8 │ ~505 GB │
├─────────┼───────────┼───────────────────────────┤
│ rtk │ 8 │ ~9 GB │
├─────────┼───────────┼───────────────────────────┤
│ Total │ │ ~514 GB │
└─────────┴───────────┴───────────────────────────┘

Worst individual grep process:
name: grep
pid: 97560
rpages: 12,126,704 (× 16384 bytes = ~198 GB)
cpuTime: 1048.6s
physicalPages.internal: [2010, 12118749]

Each rtk instance has an adjacent grep subprocess (sequential PIDs), confirming RTK spawns one grep per command
invocation. These processes do not terminate after the command completes.

Root cause hypothesis

The grep subprocesses appear to remain alive with their stdin pipe open after the parent rtk process exits. On
Unix, a process reading from a pipe blocks indefinitely if the write end is never closed. Over multiple commands,
these zombie-like grep processes accumulate memory until the system collapses.

Reproduction

Run Claude Code with the RTK PreToolUse hook active for an extended session involving large file reads or many bash
commands. Monitor memory with ps -eo pid,rss,comm | sort -k2 -rn — grep processes will grow continuously and not
exit.

Fix suggestion

Ensure grep subprocesses are killed when the parent rtk process exits — e.g., using a process group and sending
SIGKILL to the group on exit, or closing the write end of the stdin pipe e

Metadata

Metadata

Assignees

Labels

P1-criticalBloque des utilisateurs, fix ASAPbugSomething isn't workingeffort-medium1-2 jours, quelques fichiers

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions