Skip to content

Draft: Fix zombie process on process destruction - #86

Open
xtrime-ru wants to merge 3 commits into
amphp:2.xfrom
xtrime-ru:fix-posix-zombie
Open

Draft: Fix zombie process on process destruction#86
xtrime-ru wants to merge 3 commits into
amphp:2.xfrom
xtrime-ru:fix-posix-zombie

Conversation

@xtrime-ru

@xtrime-ru xtrime-ru commented Aug 24, 2026

Copy link
Copy Markdown

Summary

Ensures that the POSIX wrapper shell created by proc_open() is reaped after process termination, both with and without ext-pcntl.

Shutdown remains non-blocking while the requested command is still running.

Root cause

proc_get_status($proc)['pid'], stored as $shellPid, identifies the wrapper shell created by proc_open(). This shell is a direct child of PHP.

The requested command PID, stored as $pid, belongs to a process started by the wrapper shell. It is not a direct child of PHP, so waiting for $pid cannot reap the wrapper shell.

Shell reaping was deferred through the event loop. If the event loop did not run again after the shell exited, the shell remained a zombie. When ext-pcntl was unavailable, the cleanup path returned without performing any wait operation.

A blocking reap after kill() also requires checking signal delivery first. ESRCH means that the requested process has already exited and the wrapper shell can still be reaped. Other delivery errors must be reported instead of proceeding to a potentially blocking wait.

Changes

  • Handle posix_kill() failures, treating ESRCH as an already-exited process and throwing for other errors.
  • Reap $shellPid after kill() and after completed process destruction.
  • Keep shutdown and destruction of running processes non-blocking.
  • Use pcntl_waitpid() with EINTR handling when PCNTL is available.
  • Use proc_get_status() to reap the wrapper shell when PCNTL is unavailable.
  • Add regression coverage for signal delivery, process destruction, shutdown ordering, and shell reaping with and without PCNTL.

This corrects the POSIX shutdown handling introduced in 6c711ee.

Testing

  • Targeted regression tests: 8 tests, 15 assertions passed.
  • Psalm passed.
  • PHP CS Fixer passed.

@xtrime-ru
xtrime-ru force-pushed the fix-posix-zombie branch 5 times, most recently from 47566d0 to ffd4ab3 Compare August 26, 2026 22:21
@xtrime-ru xtrime-ru changed the title Fix zombie process on process destruction Draft: Fix zombie process on process destruction Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant