fix(coding-agent): stop macOS shell groups before killing them

Reduce the race where killing a foreground child wakes its shell before the shell is signalled. Keep Linux and Windows termination unchanged and preserve kill fallbacks when stopping fails.

closes #11252
This commit is contained in:
Petr Houška 2026-10-22 19:51:11 +02:00
parent 74f4686402
commit 27cc6bfc0c
2 changed files with 88 additions and 0 deletions

View file

@ -236,6 +236,19 @@ export function killProcessTree(pid: number): void {
// Ignore errors if taskkill fails.
}
} else {
if (process.platform === "darwin") {
// macOS signals group members individually after releasing the group lock. A killed
// child can wake its waiting shell before that shell is signalled, letting `a; b`
// start b during cancellation (#11252). Stop the group first to reduce this race;
// this is best-effort, not an atomic freeze. SIGKILL also kills stopped processes.
// Linux holds tasklist_lock across group signalling; child exit notification needs
// its write lock, so the shell is signalled before observing the killed child's exit.
try {
process.kill(-pid, "SIGSTOP");
} catch {
// A failed stop must not prevent the kill attempt or its single-process fallback.
}
}
// Use SIGKILL on Unix/Linux/Mac
try {
process.kill(-pid, "SIGKILL");