php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69014 proc_close and proc_get_status returns NULL. Zombies remain in process-list
Submitted: 2015-02-08 15:37 UTC Modified: 2015-02-22 07:09 UTC
Votes:10
Avg. Score:3.8 ± 0.7
Reproduced:10 of 10 (100.0%)
Same Version:4 (40.0%)
Same OS:4 (40.0%)
From: f0o at devilcode dot org Assigned:
Status: Open Package: Program Execution
PHP Version: 5.5.21 OS: Gentoo 2.2, Debian Jessie
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: f0o at devilcode dot org
New email:
PHP Version: OS:

 

 [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
"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-02-10 08:03 UTC] joey@php.net
-Status: Open +Status: Feedback
 [2015-02-10 08:03 UTC] joey@php.net
Not enough information was provided for us to be able
to handle this bug. Please re-read the instructions at
http://bugs.php.net/how-to-report.php

If you can provide more information, feel free to add it
to this bug and change the status back to "Open".

Thank you for your interest in PHP.


I have been unable to duplicate this bug on Debian Jessie with PHP 5.6.5 (5.6.5+dfsg-1), 5.5.21 built from source, nor 5.5.9 from Ubuntu packages.
 [2015-02-10 18:22 UTC] f0o at devilcode dot org
What information should I provide?

The link you gave me isn't really specific about it and I think I described the issue brief and as exact as I could..

I can provide USE-flags that have been used to emerge php-5.4.27, php-5.5.21, php-5.6.5 and nginx if that's helpfull.

I can also provide php.ini and fpm's configs although they are the defaults from your source-package..

Cheers,
f0o
 [2015-02-22 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2015-02-22 07:09 UTC] requinix@php.net
-Status: No Feedback +Status: Open
 [2017-04-10 18:54 UTC] seb35 at seb35 dot fr
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
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Sep 22 04:01:25 2019 UTC