-
Notifications
You must be signed in to change notification settings - Fork 444
pcntl_fork() in worker thread creates full Go runtime copy that never exits, causing unbounded process accumulation #2331
Copy link
Copy link
Open
Description
Environment
- FrankenPHP version: 1.12.1
- PHP version: 8.4
- OS: Linux (Debian bookworm, Docker container)
- Caddy config:
num_threads 2,max_threads 8
Description
When pcntl_fork() is called inside a FrankenPHP worker thread (during an HTTP request),
the child process becomes a full copy of the FrankenPHP Go runtime and never terminates —
even after calling exit(0) from PHP.
Each request that calls pcntl_fork() leaves one additional frankenphp process
in S (sleeping) state permanently. These processes accumulate indefinitely.
Reproduction
Minimal controller:
$pid = pcntl_fork();
if ($pid === 0) {
usleep(100); // 100 microseconds
exit(0);
}
Steps:
1. Run FrankenPHP with num_threads 2, max_threads 8
2. Hit the endpoint 20 times
3. Check ps aux inside the container
Before (20 requests):
3 processes
After:
23 processes — all `frankenphp run` with status `S`, never exit
Root cause (hypothesis)
pcntl_fork() in a Go-based runtime duplicates the entire Go runtime — goroutines,
mutexes, thread pools. The child process inherits locks held by threads that no
longer exist in the child, causing the Go runtime to deadlock on shutdown.
PHP's exit(0) is called but the Go process cannot clean up and terminate.
Impact
In production under load, these zombie-like sleeping processes accumulate rapidly:
- PID exhaustion
Notes
- tini as PID 1 does not help — processes are in S state, not Z (zombie),
so tini has nothing to reap
- Process::run() (Symfony/Laravel, uses proc_open) does not reproduce the issue
- Only direct pcntl_fork() call reproduces it
Question
Is pcntl_fork() expected to be unsupported inside FrankenPHP worker threads?
Should FrankenPHP disable pcntl_fork or emit a warning when called in worker context?
--- Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels