Skip to content

fix(command): 修复 Unix 进程组终止竞态 - #71

Merged
uvwt merged 1 commit into
mainfrom
fix/macos-command-shutdown-race-20260907
Sep 7, 2026
Merged

fix(command): 修复 Unix 进程组终止竞态#71
uvwt merged 1 commit into
mainfrom
fix/macos-command-shutdown-race-20260907

Conversation

@uvwt

@uvwt uvwt commented Sep 7, 2026

Copy link
Copy Markdown
Owner

问题

main 的 macOS CI 偶发失败:TestRuntimeCloseCancelsForegroundCommandAndRejectsNewStartsRuntime.Close() 阶段等待 command reservation 3s 超时。

根因

Unix killpg(SIGKILL) 与 shell fork 存在竞态:第一次 group signal 返回成功且 shell 已终止后,刚好在 signal 快照之后出生的 child 仍可能存活,并继续持有 stdout/stderr pipe,导致 cmd.Wait() 不返回,reservation 无法释放。

修复

  • 在 Unix process Controller 层对同一 PGID 做有界重复 SIGKILL(最多 5 次、间隔 1ms),覆盖 fork race。
  • 保留首次 EPERM 为真实权限错误;兼容 macOS 首次成功后 zombie-only process group 的 EPERM。
  • 不修改 Runtime/Store 生命周期,不增加 sessionKillWait,避免用更大超时掩盖竞态。
  • 新增 Unix 进程组回归测试,覆盖 shell fork + pipe 持有场景。

验证

  • 未修复的 origin/main + 新回归测试可真实复现 command pipes stayed open after process-group termination
  • 修复后 focused fork-race stress 1280 次通过。
  • 原失败生命周期测试 1000 次并行压力通过,额外 200 次提交前复验通过。
  • go test ./... 通过。
  • go test -race ./internal/process ./internal/tool/command ./internal/app 通过。
  • go vet ./...、Linux amd64 交叉编译、git diff --check 通过。

@uvwt
uvwt merged commit 5cda462 into main Sep 7, 2026
7 checks passed
@uvwt
uvwt deleted the fix/macos-command-shutdown-race-20260907 branch September 8, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant