Skip to content

Commit eb15cc0

Browse files
authored
fix: remove PR_SET_PDEATHSIG that kills Chrome after ~10s idle (#1157) (#1173)
v0.24.1 introduced `prctl(PR_SET_PDEATHSIG, SIGKILL)` in #1137 to kill Chrome when the daemon dies. However, `PR_SET_PDEATHSIG` tracks the **thread** that called `fork()`, not the process (`prctl(2)` documents this). Chrome is spawned via `tokio::task::spawn_blocking`, whose threads are reaped after ~10 seconds of idle time. When the blocking thread exits, the kernel sends SIGKILL to Chrome even though the daemon is still alive. Symptoms reported in #1157: - `tab list` shows `about:blank` after a few seconds - `snapshot` returns an empty page - All Chrome processes exit ~9 seconds after launch - Any workflow involving navigation or waiting breaks The fix removes `PR_SET_PDEATHSIG` from the Chrome `pre_exec` hook. Orphan cleanup is already handled by the process-group kill (`kill(-pgid, SIGKILL)`) in `ChromeProcess::kill()`, which runs via daemon signal handlers, `close_notify`, idle timeout, and `Drop`. Fixes #1157
1 parent 7b3f826 commit eb15cc0

File tree

1 file changed

+6
-11
lines changed

1 file changed

+6
-11
lines changed

cli/src/native/cdp/chrome.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -351,23 +351,18 @@ fn try_launch_chrome(chrome_path: &Path, options: &LaunchOptions) -> Result<Chro
351351
// Place Chrome in its own process group so we can kill the entire tree
352352
// (main process + GPU/renderer/utility/crashpad helpers) with a single
353353
// killpg(), preventing orphaned processes (issue #1113).
354+
//
355+
// NOTE: Do NOT use PR_SET_PDEATHSIG here. Chrome is spawned via
356+
// tokio::task::spawn_blocking, and PR_SET_PDEATHSIG fires when the
357+
// *thread* that forked the child exits, not the process. Tokio reaps
358+
// idle blocking threads after ~10s, which kills Chrome (issue #1157).
354359
#[cfg(unix)]
355360
{
356361
use std::os::unix::process::CommandExt;
357362
// SAFETY: pre_exec runs between fork() and exec() in the child.
358-
// Both prctl and setpgid are async-signal-safe.
363+
// setpgid is async-signal-safe.
359364
unsafe {
360365
cmd.pre_exec(|| {
361-
// On Linux, ask the kernel to send SIGKILL to this process
362-
// when the parent (daemon) dies for any reason, including
363-
// SIGKILL. This is the most robust orphan prevention
364-
// available and has no macOS equivalent.
365-
#[cfg(target_os = "linux")]
366-
{
367-
libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL);
368-
}
369-
// Create a new process group (PGID = own PID) so the
370-
// daemon can kill the entire Chrome tree in one call.
371366
libc::setpgid(0, 0);
372367
Ok(())
373368
});

0 commit comments

Comments
 (0)