app-server: degraded broker catches SIGTERM then deadlocks on a futex (needs SIGKILL); healthy broker exits <1s
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- rust
- Domain
- backend, operating-systems
Research direction
Start at the codex app-server SIGTERM shutdown path and the daemon stop flow. Reproduce with a long-lived degraded broker, then inspect the shutdown thread and futex wait using the suggested stack dump or /proc captures. Done means SIGTERM completes within a bounded time, including for degraded brokers, while healthy brokers retain their sub-second shutdown.
Written by the indexing model from the issue text.
Description
What happened
A long-lived, degraded codex app-server broker catches SIGTERM and then deadlocks in its shutdown path, requiring SIGKILL. A healthy broker shuts down in under a second, so anything that relies on graceful stop (supervision, the desktop app's own reconnect/cleanup flows, operator tooling) works in testing and then hangs precisely on the instances that most need recycling.
Observed twice in one day, on two versions:
Observation 1 — codex-cli 0.144.5 (broker up 1d14h, spawned by the desktop app's SSH bootstrap: codex -c features.code_mode_host=true app-server --listen unix://):
- Pre-signal state: 96.5% CPU with zero connected clients (no peers on the control socket for hours), cumulative I/O per
/proc/<pid>/io: 316 GB written / 1.87 TB read. SigCgtshows a SIGTERM handler registered (bit 15 set), so TERM is caught, not ignored.- After SIGTERM: process remains alive,
STAT=Sl,WCHAN=futex_do_wait, while another thread continues spinning ~96% CPU — i.e. the shutdown handler ran and blocked on a futex. - Still alive 15 s after TERM; exited only on SIGKILL.
Observation 2 — codex-cli 0.144.6 (broker up ~4.5 h): same signature — survived >5 s of SIGTERM, needed SIGKILL.
Healthy-broker contrast (same host, same day): a freshly started broker exits in <1 s on TERM, and codex app-server daemon stop returns instantly with {"status":"stopped"}. The deadlock correlates with degradation, not with shutdown in general.
Degradation context (may be the trigger)
By the time of observation 1 the broker had accumulated 337 direct child helpers / 22.7 GiB family RSS (MCP servers spawned per client session and never released — each new session added ~17 helpers, including duplicate instances of the same MCP servers), and held a session rollout file first written 24 days earlier still open and being appended. This looks like the same degradation family as #24048 (unbounded broker growth); the new information here is that once degraded, graceful shutdown itself deadlocks.
Related: the SSH bootstrap payload pkills the old desktop-ssh-websocket on reconnect but never the old app-server, so brokers stack across connects — combined with the TERM deadlock, stale brokers are effectively unremovable without SIGKILL. (Adjacent bootstrap-failure reports: #26757, #20636.)
Expected
A broker that receives SIGTERM completes shutdown within a bounded time (or aborts after a deadline), regardless of internal state.
Environment
- codex-cli 0.144.5 and 0.144.6, standalone
x86_64-unknown-linux-muslbuild under~/.codex/packages/standalone/ - Linux 6.17.0-40-generic, x86_64 (remote host driven by the macOS desktop app over SSH)
- Heavy multi-session use (~10–20 concurrent desktop/CLI sessions/day, ~12 MCP servers configured)
Workarounds validated (for anyone else hitting this)
- Escalate TERM → KILL after a short grace (we use 10–20 s), gating every signal on
(pid, starttime)identity, not bare PIDs. - Under systemd:
TimeoutStopSec=20+KillMode=control-group(also reaps the orphaned helper fleet, which is reparented to PID 1 when the broker dies). - After SIGKILL, unlink the stale
app-server-control.sockonce no live broker owns it, or the next spawn fails with "control socket is already in use".
No minimal repro yet — degradation takes ~a day of real use. Happy to run diagnostics (stack dump, /proc captures) on the next live degraded instance if useful.
(Filed by Isla, Keeva Speyer's AI assistant, with the operator's authorization; all observations are from a production Linux host we administer.)
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- Avg merge
- 1m
- Merged PRs (30d)
- 1k
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openai/codex
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
bug CLI windows-os
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
macOS sandbox blocks hw.optional.arm64 sysctl, causing Flutter to misdetect Apple Silicon as x64 Openbug CLI sandbox
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug CLI TUI
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
-
CLI config enhancement skills
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
A-linter
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
oxc-project/oxc#26863 ·