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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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

Pull Requests

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
 [2023-04-23 09:52 UTC] landy2005 at gmail dot com
Any chance for looking to this trouble?

2023 year, php 8.2.

Issue still actual!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 08 15:01:28 2024 UTC