环境
- 版本:v2.1.2(release 安装)
- 平台:Linux(Arch Linux),systemd user service,
codex 后端
- 触发场景:headless pool 高频拉起实例(
inst-headless-pool-*)
现象
当某个 headless 实例的 codex 子进程启动链路被阻塞、永远不回 initialize 应答时,launchCodexChildSession 会永久阻塞在 bootstrapHeadlessCodex,该会话进程与其整棵子进程树全部滞留,且无任何超时或退避,新实例继续被拉起,进程数无上限堆积。
本机实测 13 小时的放大过程:
- 用户 PATH 中的
codex 启动脚本(本机自建 shim,非本仓库产物)内部调用 mise use -g codex,该命令需要抢一个文件锁;上游排队进程达到上千后,每个新 codex 启动都卡在锁上,永远到不了 initialize 应答。
- wrapper 侧
bootstrapHeadlessCodex 读循环(internal/app/wrapper/app_headless.go:44)对 ReadBytes 无 deadline,launch 路径(internal/app/wrapper/app_child_session.go:52)随之永久阻塞。三条后端链路同病:app_headless.go(codex)、app_headless_claude.go(claude)、app_child_session_opencode.go(opencode)。
- 滞留进程持续累积,cgroup 任务数顶满 systemd TasksMax(本机 38071)。此后该 cgroup 内所有
clone() 返回 EAGAIN:
- codex-remote 自身 Go runtime 直接
fatal error: newosproc(errno 11),实例日志中可复现;
- 被拉起的外部命令全部 panic/失败(本机 mise 当日产生 527 个 SIGABRT coredump);
- daemon 仍持续重试拉起,故障自我放大,持续 13 小时,直到人工重启服务。
/proc/locks 实测锁队列 19+ 层深;崩溃期间 cgroup pids.current == pids.max == 38071。
根因
触发源在本机(shim 的全局写锁),但上游缺陷是它从"局部变慢"放大为"整机资源耗尽"的原因:
- bootstrap 握手无超时——子进程不应答时会话进程无限滞留;
- bootstrap 阶段不响应 ctx 取消——即使会话被要求停止也无法回收滞留中的 launch;
- launch 失败/阻塞无退避与并发上限,资源耗尽后仍以原有频率重试,crash-loop 放大故障。
建议
- 为三个 backend 的 bootstrap 握手加超时(超时后 kill 子进程并返回错误);本机 codex app-server 正常握手在 1s 内,建议 15s 量级;
- 让 bootstrap 阶段响应 ctx 取消;
- (可选)launch 失败指数退避,或在检测到资源耗尽(EAGAIN)时熔断。
我可以提交一个最小修复 PR:统一封装带超时 + ctx 取消的 bootstrap 调用,三个调用点切换过去,并附回归测试。
环境
codex后端inst-headless-pool-*)现象
当某个 headless 实例的
codex子进程启动链路被阻塞、永远不回initialize应答时,launchCodexChildSession会永久阻塞在bootstrapHeadlessCodex,该会话进程与其整棵子进程树全部滞留,且无任何超时或退避,新实例继续被拉起,进程数无上限堆积。本机实测 13 小时的放大过程:
codex启动脚本(本机自建 shim,非本仓库产物)内部调用mise use -g codex,该命令需要抢一个文件锁;上游排队进程达到上千后,每个新codex启动都卡在锁上,永远到不了 initialize 应答。bootstrapHeadlessCodex读循环(internal/app/wrapper/app_headless.go:44)对ReadBytes无 deadline,launch 路径(internal/app/wrapper/app_child_session.go:52)随之永久阻塞。三条后端链路同病:app_headless.go(codex)、app_headless_claude.go(claude)、app_child_session_opencode.go(opencode)。clone()返回 EAGAIN:fatal error: newosproc(errno 11),实例日志中可复现;/proc/locks实测锁队列 19+ 层深;崩溃期间 cgrouppids.current == pids.max == 38071。根因
触发源在本机(shim 的全局写锁),但上游缺陷是它从"局部变慢"放大为"整机资源耗尽"的原因:
建议
我可以提交一个最小修复 PR:统一封装带超时 + ctx 取消的 bootstrap 调用,三个调用点切换过去,并附回归测试。