|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-02-08 15:37 UTC] f0o at devilcode dot org
Description:
------------
'proc_get_status' and 'proc_close' return 'NULL' and leave the process as defunct/Zombie in the process-list.
The process has no open files and is verified to be terminated in execution.
PHP Versions 5.5.21 and 5.6.5 are affected.
PHP Versions 5.4.37 is NOT affected.
The bug was noticed under Gentoo 2.2 and verified under Debian Jessie.
Gentoo has been used to isolate the affected versions as it guarantees an equal build-environment for all php-installations and allows to 'hotswap' the versions at any given time.
All tests have been conducted with PHP-FPM under Nginx.
Version of Nginx has no influence on the bug.
Test script:
---------------
<?php
function pipe_open(&$process, &$pipes) {
$command = "/bin/date +%s";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$cwd = '/';
$env = array();
$process = proc_open($command, $descriptorspec, $pipes, $cwd, $env);
var_dump("Proc:");
var_dump($process);
var_dump("Status:");
var_dump(proc_get_status($process));
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
if( is_resource($process) ) {
return true;
}
}
function pipe_close($process, &$pipes) {
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
var_dump("Status:");
var_dump(proc_get_status($process));
$return_value = proc_close($process);
var_dump("RetVal:");
var_dump($return_value);
var_dump("Proc:");
var_dump($process);
return $return_value;
}
function test($param) {
pipe_open($process, $pipes);
if( is_resource($process) ) {
fwrite($pipes[0], $param);
fclose($pipes[0]);
while( strlen($line) < 1 ) {
$line = fgets($pipes[1],1024);
$data .= $line;
}
$return_value = pipe_close($process, $pipes);
return $data;
} else {
return 0;
}
}
var_dump(test(""));
?>
Expected result:
----------------
string(5) "Proc:"
resource(5) of type (process)
string(7) "Status:"
array(8) {
["command"]=>
string(13) "/bin/date +%s"
["pid"]=>
int(30731)
["running"]=>
bool(true)
["signaled"]=>
bool(false)
["stopped"]=>
bool(false)
["exitcode"]=>
int(-1)
["termsig"]=>
int(0)
["stopsig"]=>
int(0)
}
string(7) "Status:"
array(8) {
["command"]=>
string(13) "/bin/date +%s"
["pid"]=>
int(30731)
["running"]=>
bool(true)
["signaled"]=>
bool(false)
["stopped"]=>
bool(false)
["exitcode"]=>
int(-1)
["termsig"]=>
int(0)
["stopsig"]=>
int(0)
}
string(7) "RetVal:"
int(0)
string(5) "Proc:"
resource(5) of type (Unknown)
string(11) "1423408318
"
Actual result:
--------------
string(5) "Proc:"
resource(5) of type (process)
string(7) "Status:"
NULL
string(7) "Status:"
NULL
string(7) "RetVal:"
NULL
string(5) "Proc:"
resource(5) of type (process)
string(11) "1423408318
"
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Nov 02 10:00:02 2025 UTC |
I experienced something similar to this bug in MediaWiki with PHPDBG [1]. The function wfShellExec, in some words, run proc_open, then a loop with proc_get_status, stream_select, and fread. When executing the MediaWiki unit tests with PHPDBG, proc_get_status returns a running process (not null, but the array below) and then there is an indefinite stream_select. At some point, probably after the proc_get_status, the process becomes a zombie and stream_select waits really indefinitely. When I add a timeout in stream_select and then a proc_get_status just after, the proc_get_status reaps the zombie and the execution continues normally. Array ( [command] => /bin/bash '/mediawiki/includes/limit.sh' ''\''/usr/bin/djvudump'\'' '\''/mediawiki/tests/phpunit/includes/media/../../data/media/LoremIpsum.djvu'\''' 'MW_INCLUDE_STDERR=;MW_CPU_LIMIT=180; MW_CGROUP='\'''\''; MW_MEM_LIMIT=307200; MW_FILE_SIZE_LIMIT=102400; MW_WALL_CLOCK_LIMIT=180; MW_USE_LOG_PIPE=yes' [pid] => 11772 [running] => 1 [signaled] => [stopped] => [exitcode] => -1 [termsig] => 0 [stopsig] => 0 ) In this specific case, I set "ulimit -Sn 4096" before running PHPDBG, and I know stream_select has an internal issue because, with the timeout, there is the error: stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE. It is set to 1024, but you have descriptors numbered at least as high as 2267. --enable-fd-setsize=3072 is recommended, but you may want to set it to equal the maximum number of open files supported by your system, in order to avoid seeing this error again at a later date. Hope it can help. I was not able to reproduce the bug here with the proposed program, I obtain the Expected result. [1] https://phabricator.wikimedia.org/T72357#3167810 With MediaWiki Git#c5eab986eed, run phpdbg -qrr tests/phpunit/phpunit.php