Summary
The launcher can get stuck before Electron ever starts, spinning one awk process at 100% CPU indefinitely. The app never opens and any tray/menu relaunch hangs the same way. Root cause is the GPU-fatal detection in launcher-common.sh reading the entire launcher.log with quadratic string accumulation, combined with the fact that launcher.log is never rotated/truncated and can grow to tens of MB (in my case 67 MB, flooded by WebRTC audio error spam).
Environment
- Package:
claude-desktop 1.15200.0-2.0.22 (.deb)
- Electron: 41.5.0
- OS: Debian 13 (trixie), X11
- Display backend: X11 (
XDG_SESSION_TYPE=x11)
Symptoms
- App stops launching; tray icon gone.
- A single
awk child of /usr/bin/claude-desktop pegs one core at ~100% and never exits:
juan 82593 bash /usr/bin/claude-desktop
juan 82624 99.9 awk '/^--- Claude Desktop (Launcher|AppImage) Start... .cache/claude-desktop-debian/launcher.log
launcher.log had grown to 67 MB / ~453k lines / 208 launch sections.
Root cause
_previous_launch_hit_gpu_fatal() (launcher-common.sh:196) runs:
{
sections[section] = sections[section] $0 "\n" # <-- O(n²) string growth
}
This accumulates the whole log file into in-memory section strings via repeated concatenation. Awk reallocates and copies an ever-growing string per line, so cost is quadratic in file size. At ~67 MB it effectively never finishes, and setup_electron_env (which calls it) blocks → Electron is never exec'd.
Two compounding problems make this reachable in normal use:
- No log rotation.
setup_logging() only does mkdir; launcher.log grows without bound across launches.
- WebRTC audio spam. During sessions with audio/voice the log fills with thousands of lines/sec like:
ERROR:.../neteq/comfort_noise.cc:50] No multi-channel support
ERROR:.../neteq/neteq_impl.cc:826] audio_frame->samples_per_channel_ (480) != output_size_samples_ (480)
A single long session bloats the penultimate section — exactly the one the awk targets.
Impact
Once the log is large enough, the app becomes unlaunchable until the user finds and kills the awk and clears the log. Nothing on screen explains why.
Suggested fixes
- Don't scan the whole file. Only the previous launch section is needed. Read the log tail (e.g. last N KB, or seek to the second-to-last
--- ... Start --- header) instead of accumulating every section. Even just tail -c <bytes> piped into the matcher would bound the cost.
- Avoid O(n²) accumulation. Track only the current/previous section, or scan backwards; never build an unbounded concatenated string.
- Rotate/truncate
launcher.log. Cap size (e.g. truncate to last N lines if > a few MB) in setup_logging().
- Tame the WebRTC audio error spam (or downgrade/suppress those Chromium ERROR lines), which is what drives the log growth in the first place.
Workarounds (for other users hitting this)
- Kill the stuck
awk + launcher, back up and truncate ~/.cache/claude-desktop-debian/launcher.log.
- Set
CLAUDE_DISABLE_GPU=0 in the launch environment. Because of the [[ -v CLAUDE_DISABLE_GPU ]] guard in setup_electron_env, defining the var makes the launcher skip _previous_launch_hit_gpu_fatal() entirely (and =0 keeps hardware acceleration on). A user-level ~/.local/share/applications/claude-desktop.desktop override with Exec=env CLAUDE_DISABLE_GPU=0 /usr/bin/claude-desktop %u makes the bypass stick for tray/menu launches and survives package upgrades.
Summary
The launcher can get stuck before Electron ever starts, spinning one
awkprocess at 100% CPU indefinitely. The app never opens and any tray/menu relaunch hangs the same way. Root cause is the GPU-fatal detection inlauncher-common.shreading the entirelauncher.logwith quadratic string accumulation, combined with the fact thatlauncher.logis never rotated/truncated and can grow to tens of MB (in my case 67 MB, flooded by WebRTC audio error spam).Environment
claude-desktop1.15200.0-2.0.22(.deb)XDG_SESSION_TYPE=x11)Symptoms
awkchild of/usr/bin/claude-desktoppegs one core at ~100% and never exits:launcher.loghad grown to 67 MB / ~453k lines / 208 launch sections.Root cause
_previous_launch_hit_gpu_fatal()(launcher-common.sh:196) runs:{ sections[section] = sections[section] $0 "\n" # <-- O(n²) string growth }This accumulates the whole log file into in-memory section strings via repeated concatenation. Awk reallocates and copies an ever-growing string per line, so cost is quadratic in file size. At ~67 MB it effectively never finishes, and
setup_electron_env(which calls it) blocks → Electron is never exec'd.Two compounding problems make this reachable in normal use:
setup_logging()only doesmkdir;launcher.loggrows without bound across launches.Impact
Once the log is large enough, the app becomes unlaunchable until the user finds and kills the awk and clears the log. Nothing on screen explains why.
Suggested fixes
--- ... Start ---header) instead of accumulating every section. Even justtail -c <bytes>piped into the matcher would bound the cost.launcher.log. Cap size (e.g. truncate to last N lines if > a few MB) insetup_logging().Workarounds (for other users hitting this)
awk+ launcher, back up and truncate~/.cache/claude-desktop-debian/launcher.log.CLAUDE_DISABLE_GPU=0in the launch environment. Because of the[[ -v CLAUDE_DISABLE_GPU ]]guard insetup_electron_env, defining the var makes the launcher skip_previous_launch_hit_gpu_fatal()entirely (and=0keeps hardware acceleration on). A user-level~/.local/share/applications/claude-desktop.desktopoverride withExec=env CLAUDE_DISABLE_GPU=0 /usr/bin/claude-desktop %umakes the bypass stick for tray/menu launches and survives package upgrades.