Process stuck in emoji width calculation loop (high CPU, unresponsive)

Resolved 💬 7 comments Opened Feb 7, 2026 by greogory Closed Mar 17, 2026

Bug Description

Claude Code process became stuck in a CPU-burning loop (94.7% CPU) performing Unicode emoji width calculations. The process was unresponsive to SIGTERM and required SIGKILL to terminate.

Environment

  • Claude Code Version: 2.1.25
  • OS: CachyOS (Arch-based), Linux 6.18.8-3-cachyos
  • Platform: x86_64
  • Terminal: Konsole (KDE)

Symptoms

| Metric | Value |
|--------|-------|
| CPU Usage | 94.7% (single core) |
| Memory | 3.3 GB RSS |
| Runtime before stuck | ~58 minutes |
| Network connections | None (not communicating with API) |
| Response to SIGTERM | Ignored |

Root Cause Analysis (from core dump)

Syscall Pattern

The process was in a tight loop performing:

pread64(10, "...", 256, 0)  # Reading /proc/self/statm repeatedly
madvise(..., MADV_DODUMP)   # Memory management
sched_yield()               # CPU yielding (busy-wait pattern)
futex(...)                  # Thread synchronization

Code Location

The main thread was stuck in JIT-compiled JavaScript performing emoji codepoint range comparisons:

cmp    $0x1f18e,%edx   ; U+1F18E (🆎 NEGATIVE SQUARED AB)
cmp    $0x1f200,%edx   ; U+1F200 (🈀 SQUARE HIRAGANA HOKA)
cmp    $0x1f440,%edx   ; U+1F440 (👀 EYES)
cmp    $0x1f4ff,%edx   ; U+1F4FF (📿 PRAYER BEADS)
cmp    $0x1f54b,%edx   ; U+1F54B (🕋 KAABA)
cmp    $0x1f595,%edx   ; U+1F595 (🖕 MIDDLE FINGER)
cmp    $0x1f3f4,%edx   ; U+1F3F4 (🏴 BLACK FLAG)
... (extensive emoji range checks)

This appears to be terminal character width calculation code (determining if characters are single or double-width for display).

Data Being Processed

Memory dump showed UTF-16 encoded session JSON:

[{"uuid": "cd8552d2-09c5-411d-b523-461eb6af357f", "name": "", "summary": "", "created_at": "2025-10...

Thread State

  • 49 total threads
  • Main thread: Running (stuck in emoji width loop)
  • Worker threads (LWP 826173-826196): Sleeping on syscall() (futex wait)
  • Helper threads (LWP 814270-814277): Sleeping on libc functions
  • Child process: clangd language server (idle)

Reproduction

Unknown exact trigger. The process was running for ~58 minutes before becoming stuck. Likely triggered by:

  1. Loading/rendering session history with specific Unicode content
  2. Possible interaction with V8 garbage collection (evidenced by /proc/self/statm polling)

Workaround

Process required kill -9 (SIGKILL) to terminate. SIGTERM was ignored because the process never yielded to check for signals.

Additional Context

  • The session with UUID cd8552d2-09c5-411d-b523-461eb6af357f may contain triggering content
  • Core dump analysis performed with GDB showed the process was not making any network I/O
  • The combination of emoji width calculation + GC memory monitoring suggests heap pressure may have contributed

Suggested Investigation

  1. Review the emoji/Unicode width calculation code path for potential infinite loops
  2. Check for edge cases in character width detection that could cause pathological behavior
  3. Consider adding a timeout or yielding mechanism in the width calculation loop
  4. Review GC behavior when processing large session histories

View original on GitHub ↗

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