spawnCapture 等 close(stdio 全关)而非 exit(进程退出)。两类逃逸会让
close 永不触发、Promise 永不 settle,调用方 await 卡死(recursive gate
卡死 86min 实况):
1. 超时只 kill 直接子进程 → sh -c 的孙进程(cargo-mutants 等)逃逸后
继续持有 stdout/stderr 管道。改为 killTree 整树 kill:SIGSTOP 冻结根
防 fork 竞态(sh 被 CPU 饿死时会在快照与 kill 之间才 fork 出子进程,
实测复现),ps 快照后代,叶子先杀,SIGTERM → 5s → SIGKILL 两级。
2. 子进程 exit 后 stdio 仍被逃逸孙进程(daemon 化/后台进程继承管道)
持有 → close 不触发。加 exit 后限时 failsafe(FLOWCAST_CLOSE_GRACE_MS
默认 3s)强制收尾并带截断标记,保证 Promise 必 settle。
test/spawn.test.js 覆盖两类逃逸场景。全量 420 tests 通过(仅剩 Node
test runner 已知 IPC deserialize flake)。