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
This commit is contained in:
@@ -351,23 +351,18 @@ fn try_launch_chrome(chrome_path: &Path, options: &LaunchOptions) -> Result<Chro
|
|||||||
// Place Chrome in its own process group so we can kill the entire tree
|
// Place Chrome in its own process group so we can kill the entire tree
|
||||||
// (main process + GPU/renderer/utility/crashpad helpers) with a single
|
// (main process + GPU/renderer/utility/crashpad helpers) with a single
|
||||||
// killpg(), preventing orphaned processes (issue #1113).
|
// killpg(), preventing orphaned processes (issue #1113).
|
||||||
|
//
|
||||||
|
// NOTE: Do NOT use PR_SET_PDEATHSIG here. Chrome is spawned via
|
||||||
|
// tokio::task::spawn_blocking, and PR_SET_PDEATHSIG fires when the
|
||||||
|
// *thread* that forked the child exits, not the process. Tokio reaps
|
||||||
|
// idle blocking threads after ~10s, which kills Chrome (issue #1157).
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
// SAFETY: pre_exec runs between fork() and exec() in the child.
|
// SAFETY: pre_exec runs between fork() and exec() in the child.
|
||||||
// Both prctl and setpgid are async-signal-safe.
|
// setpgid is async-signal-safe.
|
||||||
unsafe {
|
unsafe {
|
||||||
cmd.pre_exec(|| {
|
cmd.pre_exec(|| {
|
||||||
// On Linux, ask the kernel to send SIGKILL to this process
|
|
||||||
// when the parent (daemon) dies for any reason, including
|
|
||||||
// SIGKILL. This is the most robust orphan prevention
|
|
||||||
// available and has no macOS equivalent.
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
|
||||||
libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL);
|
|
||||||
}
|
|
||||||
// Create a new process group (PGID = own PID) so the
|
|
||||||
// daemon can kill the entire Chrome tree in one call.
|
|
||||||
libc::setpgid(0, 0);
|
libc::setpgid(0, 0);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user