Skip to content

fix: don't kill grandchildren of forked processes - #2703

Merged
dunglas merged 1 commit into
mainfrom
fix/atfork-grandchildren
Oct 10, 2026
Merged

dunglas merged 1 commit into
mainfrom
fix/atfork-grandchildren

Conversation

@dunglas

@dunglas dunglas commented Oct 10, 2026

Copy link
Copy Markdown
Member

Fixes #2689, a regression since 1.12.5.

#2390 added a pthread_atfork child handler that ties each forked child to its parent's lifetime: PR_SET_PDEATHSIG on Linux, procctl on FreeBSD, a kqueue watcher on macOS and the other BSDs.

Fork handlers survive fork(); only exec() clears them. When a forked child forks again without exec'ing, the handler runs again and ties the grandchild to the short-lived intermediate process. gpgme (used by the gnupg extension) double-forks to start gpgconf, so the grandchild is killed as soon as the intermediate exits, and gnupg fails with "could not init keylist".

The handler now returns early in a process that is already a forked child. Only direct children of FrankenPHP get the protection. Grandchildren still inherit is_forked_child, so the SAPI output guards still apply.

The new test forks twice from PHP. It needs pcntl and skips without it. With pcntl loaded, it fails on main (grandchild-killed) and passes with the fix.

The atfork child handler ties each forked child to its parent's lifetime.
atfork handlers survive fork, so a child that forks again without exec'ing
tied the grandchild to the short-lived intermediate process. Double-forking
code such as gpgme (used by the gnupg extension to run gpgconf) had its
grandchild killed as soon as the intermediate exited. Only protect direct
children of the FrankenPHP process.

Fixes #2689
@dunglas
dunglas marked this pull request as ready for review October 10, 2026 06:13
@dunglas
dunglas merged commit 3f79bcb into main Oct 10, 2026
40 of 41 checks passed
@dunglas
dunglas deleted the fix/atfork-grandchildren branch October 10, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gnupg extension broken since 1.12.5: "could not init keylist"

1 participant