fix(core): track PIDs independently to survive removeProcess() race during shutdown
The direct child process may die from terminal SIGINT before ProcessLifecycle runs shutdown, causing removeProcess() to clear it. Now killAll() uses a persistent trackedPids Set that is never cleared by removeProcess(), ensuring grandchild process trees are always killed.
This commit is contained in:
@@ -187,22 +187,18 @@ export class ProcessLifecycle {
|
||||
});
|
||||
}
|
||||
|
||||
/** Synchronous last-resort: SIGKILL any remaining child processes. */
|
||||
/** Synchronous last-resort: SIGKILL any remaining tracked PIDs. */
|
||||
private handleExit(): void {
|
||||
const instances = ProcessLifecycle.getInstances();
|
||||
let killed = 0;
|
||||
|
||||
for (const instance of instances) {
|
||||
const processes = instance.processesToEnd.getArray();
|
||||
for (const child of processes) {
|
||||
const pid = child.pid;
|
||||
if (pid && !child.killed) {
|
||||
try {
|
||||
process.kill(pid, 'SIGKILL');
|
||||
killed++;
|
||||
} catch {
|
||||
// Process may already be dead
|
||||
}
|
||||
for (const pid of instance.trackedPids) {
|
||||
try {
|
||||
process.kill(pid, 'SIGKILL');
|
||||
killed++;
|
||||
} catch {
|
||||
// Process already dead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user