|
| 1 | +// Does a Chrome launched by a node parent survive SIGKILL of that parent? pipe-only vs pipe+port, 3 trials each. |
| 2 | +import { spawn } from "node:child_process"; |
| 3 | +import { mkdtempSync } from "node:fs"; |
| 4 | +import { tmpdir } from "node:os"; |
| 5 | +import { join } from "node:path"; |
| 6 | +import { createRequire } from "node:module"; |
| 7 | + |
| 8 | +const chrome = process.argv[2]; |
| 9 | +if (process.argv[3] === "child") { |
| 10 | + const puppeteer = createRequire(join(process.cwd(), "packages/cli/package.json"))("puppeteer-core"); |
| 11 | + const args = process.argv[4] === "port" ? ["--remote-debugging-port=0"] : []; |
| 12 | + const b = await puppeteer.launch({ executablePath: chrome, pipe: true, headless: true, |
| 13 | + userDataDir: mkdtempSync(join(tmpdir(), "cf-pipekill-")), args }); |
| 14 | + const p = await b.newPage(); |
| 15 | + await p.goto("about:blank"); |
| 16 | + console.log(`PID ${b.process().pid}`); |
| 17 | + setInterval(() => {}, 1000); |
| 18 | +} else { |
| 19 | + const alive = (pid) => { try { process.kill(pid, 0); return true; } catch { return false; } }; |
| 20 | + const wait = (ms) => new Promise((r) => setTimeout(r, ms)); |
| 21 | + let failures = 0; |
| 22 | + for (const mode of ["pipe", "port"]) { |
| 23 | + for (let t = 1; t <= 3; t++) { |
| 24 | + const child = spawn(process.execPath, [process.argv[1], chrome, "child", mode], { stdio: ["ignore", "pipe", "inherit"] }); |
| 25 | + const pid = await new Promise((resolve) => { |
| 26 | + let out = ""; |
| 27 | + child.stdout.on("data", (d) => { out += d; const m = out.match(/PID (\d+)/); if (m) resolve(Number(m[1])); }); |
| 28 | + }); |
| 29 | + child.kill("SIGKILL"); |
| 30 | + await wait(3000); |
| 31 | + const survived = alive(pid); |
| 32 | + console.log(`${process.platform} ${mode} trial${t} chrome ${pid} ${survived ? "ALIVE" : "exited"}`); |
| 33 | + if (survived) { |
| 34 | + if (mode === "pipe") failures++; |
| 35 | + if (process.platform === "win32") spawn("taskkill", ["/PID", String(pid), "/T", "/F"]); |
| 36 | + else process.kill(pid, "SIGKILL"); |
| 37 | + await wait(1000); |
| 38 | + } |
| 39 | + } |
| 40 | + } |
| 41 | + process.exit(failures ? 1 : 0); |
| 42 | +} |
0 commit comments