php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64577 die or exit on solaris leaves open file descriptors
Submitted: 2013-04-03 18:59 UTC Modified: 2013-04-05 02:30 UTC
From: davek at gamehouse dot com Assigned: rasmus
Status: Closed Package: Apache2 related
PHP Version: 5.4.13 OS: solaris 11
Private report: No CVE-ID:
 [2013-04-03 18:59 UTC] davek at gamehouse dot com
Description:
------------
apache 2.4.3 : mod_prefork, keepAlive = Off
php 5.3.23 : ../php-5.3.23/configure' '--prefix=/opt/ghc/services/php/php5.3.23' 
'--with-apxs2=/opt/ghc/services/apache/apache2.4.3-php/bin/apxs' '--with-config-
file-path=/opt/ghc/services/php/php5.3.23/lib' '--disable-all'

phpinfo.php:

<?php
phpinfo();
die();


Test script:
---------------
server> ./bin/httpd -X &
server> pfiles $(pgrep httpd) |awk '{print $1}' |grep ^[[:digit:]] |wc -l
12

server> pfiles $(pgrep httpd) 
25087:  ./bin/httpd -X -f /opt/ghc/conf/php_conf/conf/httpd.conf
  Current rlimit: 1024 file descriptors
   0: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:320891
   1: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:320891
   2: S_IFREG mode:0644 dev:90,65567 ino:99347 uid:0 gid:0 size:5322
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE
      /opt/ghc/conf/php_conf/logs/error_log
      offset:5322
   3: S_IFSOCK mode:0666 dev:540,0 ino:10 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
        SOCK_STREAM
        SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128000)
        sockname: AF_INET 192.168.27.57  port: 80
   4: S_IFDOOR mode:0444 dev:542,0 ino:90 uid:0 gid:0 size:0
      O_RDONLY|O_LARGEFILE FD_CLOEXEC  door to nscd[9126]
      /var/run/name_service_door
   5: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR|O_NONBLOCK FD_CLOEXEC
   6: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   7: S_IFREG mode:0644 dev:90,65567 ino:97687 uid:0 gid:0 size:0
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE FD_CLOEXEC
      /opt/ghc/conf/php_conf/logs/access_log
      offset:0
   8: S_IFIFO mode:0000 dev:530,0 ino:21648221 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   9: S_IFPORT mode:0000 dev:543,0 uid:103 gid:1 size:0
  10: S_IFIFO mode:0000 dev:530,0 ino:21648222 uid:0 gid:0 size:0
      O_RDWR


client> curl http://server/phpinfo.php


server> pfiles $(pgrep httpd) |awk '{print $1}' |grep ^[[:digit:]] |wc -l
13

server> pfiles $(pgrep httpd) 
25087:  ./bin/httpd -X -f /opt/ghc/conf/php_conf/conf/httpd.conf
  Current rlimit: 1024 file descriptors
   0: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:324283
   1: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:324283
   2: S_IFREG mode:0644 dev:90,65567 ino:99347 uid:0 gid:0 size:5322
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE
      /opt/ghc/conf/php_conf/logs/error_log
      offset:5322
   3: S_IFSOCK mode:0666 dev:540,0 ino:10 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
        SOCK_STREAM
        SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128000)
        sockname: AF_INET 192.168.27.57  port: 80
   4: S_IFDOOR mode:0444 dev:542,0 ino:90 uid:0 gid:0 size:0
      O_RDONLY|O_LARGEFILE FD_CLOEXEC  door to nscd[9126]
      /var/run/name_service_door
   5: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR|O_NONBLOCK FD_CLOEXEC
   6: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   7: S_IFREG mode:0644 dev:90,65567 ino:97687 uid:0 gid:0 size:0
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE FD_CLOEXEC
      /opt/ghc/conf/php_conf/logs/access_log
      offset:0
   8: S_IFIFO mode:0000 dev:530,0 ino:21648221 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   9: S_IFPORT mode:0000 dev:543,0 uid:103 gid:1 size:0
  10: S_IFIFO mode:0000 dev:530,0 ino:21648222 uid:0 gid:0 size:0
      O_RDWR
  13: S_IFDIR mode:0755 dev:90,65567 ino:21918 uid:0 gid:0 size:22
      O_RDONLY
      /opt/ghc/services/apache/apache2.4.3-php
      offset:0

client> curl http://server/phpinfo.php


server> pfiles $(pgrep httpd) |awk '{print $1}' |grep ^[[:digit:]] |wc -l
14

server> pfiles $(pgrep httpd) 
25087:  ./bin/httpd -X -f /opt/ghc/conf/php_conf/conf/httpd.conf
  Current rlimit: 1024 file descriptors
   0: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:327991
   1: S_IFCHR mode:0620 dev:533,11 ino:920560006 uid:0 gid:7 rdev:6,1
      O_RDWR|O_NOCTTY|O_LARGEFILE
      /dev/pts/1
      offset:327991
   2: S_IFREG mode:0644 dev:90,65567 ino:99347 uid:0 gid:0 size:5322
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE
      /opt/ghc/conf/php_conf/logs/error_log
      offset:5322
   3: S_IFSOCK mode:0666 dev:540,0 ino:10 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
        SOCK_STREAM
        SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128000)
        sockname: AF_INET 192.168.27.57  port: 80
   4: S_IFDOOR mode:0444 dev:542,0 ino:90 uid:0 gid:0 size:0
      O_RDONLY|O_LARGEFILE FD_CLOEXEC  door to nscd[9126]
      /var/run/name_service_door
   5: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR|O_NONBLOCK FD_CLOEXEC
   6: S_IFIFO mode:0000 dev:530,0 ino:21648220 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   7: S_IFREG mode:0644 dev:90,65567 ino:97687 uid:0 gid:0 size:0
      O_WRONLY|O_APPEND|O_CREAT|O_LARGEFILE FD_CLOEXEC
      /opt/ghc/conf/php_conf/logs/access_log
      offset:0
   8: S_IFIFO mode:0000 dev:530,0 ino:21648221 uid:0 gid:0 size:0
      O_RDWR FD_CLOEXEC
   9: S_IFPORT mode:0000 dev:543,0 uid:103 gid:1 size:0
  10: S_IFIFO mode:0000 dev:530,0 ino:21648222 uid:0 gid:0 size:0
      O_RDWR
  13: S_IFDIR mode:0755 dev:90,65567 ino:21918 uid:0 gid:0 size:22
      O_RDONLY
      /opt/ghc/services/apache/apache2.4.3-php
      offset:0
  14: S_IFDIR mode:0755 dev:90,65567 ino:17614 uid:103 gid:1 size:20
      O_RDONLY
      /opt/ghc/webroots/php_content
      offset:0

Expected result:
----------------
I'd expect that FD's don't leak.

Actual result:
--------------
every call adds another open FD.
I've traced this to main/main.c 2266


PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
{
...
...
>            old_cwd_fd = open(".", 0);
...
            VCWD_CHDIR_FILE(primary_file->filename);
...
...
zend_try {
...
 retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 3, prepend_file_p, 
primary_file, append_file_p) == SUCCESS);
} zend_end_try()
...
...
// close old_cwd_fd code
}

-- looks to me that the objective is to move the process into the directory of 
the script.  I thought that moving the close of the FD to right after the move 
[VCWD-CHDIR_FILE()] would cleanup the open FD and it does, However why is this 
happening in the first place?  I ran the same test on my OSX workstation and 
FD's don't accumulate.  


Patches

bug.64577.main.c.patch (last revision 2013-04-04 20:44 UTC) by davek at gamehouse dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-04-03 19:02 UTC] davek at gamehouse dot com
this may be related to https://bugs.php.net/bug.php?id=47675 
and https://bugs.php.net/bug.php?id=60978

I'll verify that I can reproduce the issue with php 5.4
 [2013-04-03 21:00 UTC] davek at gamehouse dot com
I build php 5.4.13 and re-ran the test.  Same result: open FD's accumulate.
 [2013-04-04 20:56 UTC] davek at gamehouse dot com
-PHP Version: 5.3.23 +PHP Version: 5.4.13
 [2013-04-04 20:56 UTC] davek at gamehouse dot com
Resolved:

  Worked with our hosting company, joyent, on this.  It was pointed out that they had 
solved this issue about two years ago (https://bugs.php.net/bug.php?id=47675).  I had 
found that bug report before creating this one as I saw that the code change had been 
added. However... 

I didn't see this at first but looking more closely, when I look at my version of 
main.c, old_cwd_fd is declared without the 'volatile' modifier.   After reading up on 
setjmp/longjmp and the use of volatile, I added it in, re-compiled and the issue is 
resolved.   It's clear in bug 47675 that the volatile modifier is there however it's 
not been added into the code repository.  Will this be added?
 [2013-04-05 02:30 UTC] rasmus@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: rasmus
 [2013-04-05 02:30 UTC] rasmus@php.net
volatile patch committed - will be in the next batch of releases
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 19:02:15 2014 UTC