php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47640 Session does not unlock file in /tmp/
Submitted: 2009-03-13 10:06 UTC Modified: 2013-10-15 11:54 UTC
Votes:20
Avg. Score:4.7 ± 0.7
Reproduced:20 of 20 (100.0%)
Same Version:2 (10.0%)
Same OS:14 (70.0%)
From: manuel dot schmitt at manitu dot de Assigned:
Status: No Feedback Package: Session related
PHP Version: 5.2.9 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2009-03-13 10:06 UTC] manuel dot schmitt at manitu dot de
Description:
------------
PHP internal session handler does not correctly closes flock()s on session files

Reproduce code:
---------------
(This bug seems the same issue as bug #32092)

The problem happens on various PHP applications, no matter what they do exactly. Only one same thing: They are all using PHP sessions.

In these cases Apache/PHP-processes hanging forever (until killed). I have strace'd the processed, they are hanging on flock()ing the session file as

   flock(FILE_ID, LOCK_EX, <unfinished>)

where FILE_ID is a /tmp/sess_XXX-File (not on NFS, just local) [I have traced this from /proc/PROCID/fd/FILE_ID which links to the session file]

I suppose that there was an php process flock()ing the file, perhaps running into max_execution_time, not unflocking the session file correctly and other processed wanting to write session data.


Expected result:
----------------
PHP session handler should have some timeout and/or old file locks should be hard-broken.

Actual result:
--------------
Forever-Hanging php processes.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-03-15 11:24 UTC] manuel dot schmitt at manitu dot de
The most simple script at all

<?php
session_start();
?>

can cause the problem, please take my notes I posted before into attention.
 [2009-03-15 12:19 UTC] jani@php.net
Please provide script(s) that reliably can be used to reproduce this. 
I can not reproduce this anywhere (even high traffic sites using 
sessions). Just saying something happens does not make it true..
 [2009-03-16 08:07 UTC] manuel dot schmitt at manitu dot de
E.g. any S9Y installation does reproduce this. I cannot post this here because it has lots of files.

BUT as I told you I said what I suppose. I suppose that scripts running into any php limit (e.g. execution time) do not properly close the session files. It does NOT happen when scripts are correctly finished!
 [2009-03-16 16:25 UTC] jani@php.net
I'm actually running also s9y installation in the high traffic 
server. Never had any hanging PHP processes. And many times scripts 
have run to limits due to database being too slow. Still, no hangups 
with sessions. As this is quite impossible to reproduce, please try 
and figure out what really causes it. I know it's hard but otherwise 
we can keep on guessing and that's pretty useless.
 [2009-03-16 16:29 UTC] manuel dot schmitt at manitu dot de
But how should I trace this anymore?

I can strace apache/php processes seeing that there is a PHP script doing flock() on a file, the process never returns.

What should I do?
 [2009-03-16 23:46 UTC] jani@php.net
You need to come up with a script / set of scripts which can be used 
to _reliably_ reproduce the issue.
 [2009-03-17 06:32 UTC] manuel dot schmitt at manitu dot de
ARGH!

It is so simple!

<?php

session_start();
while (true) { $i *= 2; }

?>

Execute it for the first time and ensure, that it runs into any of the php limits, e.g. maxmimum execution time.

Call the script a second time while not running into the limit. When tracing the PHP process you will see an unlimited flock() syscall!
 [2009-05-02 18:42 UTC] jani@php.net
Endless loops tend to cause such problems. One should always use http://www.php.net/session_write_close as early as possible to prevent 
race conditions and this kind of "bugs".
 [2009-05-03 12:07 UTC] manuel dot schmitt at manitu dot de
ACK, but as server administrator there *must* be a way to prevent this.

Admins do not have influence on the scripts that are used by webmasters.

So I think it's a PHP thing. Likely one should automatically close all sessions that were opened by scripts aborting / running into limits sets by php (e.g. exec time) etc. This should solve it.
 [2010-10-24 12:29 UTC] alex dot linte at gmail dot com
Hello,

I have the same mistake :

host:~# date
dimanche 24 octobre 2010, 12:10:03 (UTC+0200)
host:~# ps faux | grep php
juritrav 17749  0.0  0.0 118988 11616 ?        S    00:11   0:00  |   \_ /usr/bin/php-cgi
suphpuser 17818  0.0  0.0 117764  9536 ?        S    00:12   0:00  |   \_ /usr/bin/php-cgi
suphpuser 18004  0.0  0.0 117764  9536 ?        S    00:14   0:00  |   \_ /usr/bin/php-cgi
suphpuser 12573  0.0  0.1 138812 31784 ?        S    09:39   0:00  |   \_ /usr/bin/php-cgi
suphpuser 12574  0.0  0.0 117492  9396 ?        S    09:39   0:00  |   \_ /usr/bin/php-cgi
duphpuser 12594  0.0  0.0 117492  9396 ?        S    09:39   0:00  |   \_ /usr/bin/php-cgi
suphpuser 12675  0.0  0.0 117764  9536 ?        S    09:40   0:00  |   \_ /usr/bin/php-cgi
suphpuser 12682  0.0  0.0 117764  9536 ?        S    09:40   0:00  |   \_ /usr/bin/php-cgi
suphpuser 12695  0.0  0.0 117764  9536 ?        S    09:40   0:00  |   \_ /usr/bin/php-cgi

So php-cgi scripts run for ever until I kill its manually.

I take the sample of process 18004 : 


front2:~# strace -p18004
Process 18004 attached - interrupt to quit
flock(3, LOCK_EX


host# lsof -p18004
....
php-cgi 18004 suphpuser    3uW  REG    9,1       7   897723 /tmp/php5/sess_xxxxxxxxxxxxxxxxxxxxxxxx (deleted)
....

So the php script tries to lock a session file (file descriptor 3) that has been deleted by the PHP garbage collector.

When the garbage collector delete a session file, it doesn't take care that any php process still using this session file.
Then the php process can't lock the file because it doesn't exist anymore, the php-cgi process is blocked....

I have the problem with the following version of php :

PHP 5.2.6-1+lenny9 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug  4 2010 06:06:53)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with Zend Optimizer v3.3.9, Copyright (c) 1998-2009, by Zend Technologies

The cron job for php (script that delete session on debian) is disabled et the garbage collector php is enabled in php.ini file :

session.gc_probability = 1
session.gc_divisor     = 100


Sorry for my english.

Alexandre LINTE
 [2012-02-01 19:50 UTC] pio at rdl dot pl
Hello !

Is there any news with this issue ?

Piotr
 [2012-05-27 01:04 UTC] bugs dot php dot net at jrs-s dot net
I worked around this problem by simply moving sessions from file storage to 
memcache.

session.save_handler = memcache
session.save_path = "tcp://serv01:11211,tcp://serv02:11211,tcp://serv03:11211"

An application pool that had been creeping up to MaxCli (900 children apiece, in 
this case) within a couple hours of a restart due to this FLOCK issue settled 
down and has now been running happily for several days on fewer than 150 
children per server.  I highly recommend just NOT USING php's file based session 
storage in the first place, because of exactly this issue.
 [2012-09-11 20:39 UTC] kriscraig@php.net
Could somebody explain why the status was changed to "Not a bug?"  I'm not seeing 
anything in the comments to indicate why that edit was made.  Looks like a real 
bug to me and everything else seems to check-out, so I'm assuming that was an 
error given the lack of an explanation.

I'm re-opening this with "Feedback" status.  If you're the one who closed this 
(the edit history is empty), please post a comment explaining your reasoning.  
Thanks!
 [2012-09-11 20:39 UTC] kriscraig@php.net
-Status: Not a bug +Status: Feedback
 [2012-09-12 03:10 UTC] laruence@php.net
...maybe it's chagned by the reporter self, no action history log in the changes 
tab
 [2012-09-12 03:14 UTC] aharvey@php.net
Explanation provided separately, since it's not relevant to this bug. Bug reopened.
 [2012-09-12 03:14 UTC] aharvey@php.net
-Summary: Session does not close file in /tmp/ +Summary: Session does not unlock file in /tmp/ -Status: Feedback +Status: Open
 [2012-09-12 17:56 UTC] connie at jaygoss dot com
I just encountered this bug on version 5.3.13. The script worked fine for about 
a year, then stopped working for no known reason (no code changes, version 
upgrades, etc.)

This script works:

echo "<br>Flock Test Without Session<br>"; 
$fp = fopen("_order_id.txt", "r+");
if (flock($fp, LOCK_EX)) { 
    /* do an exclusive lock to get an order number */
    $id = fread($fp,filesize("_order_id.txt"));
    $id++;
    echo "<br>Got the lock, id is now $id";
    ftruncate($fp, 0); /* truncate file */
    rewind($fp); /* reset pointer */
    fwrite($fp, $id); /* write new order id */
    flock($fp, LOCK_UN); /* release the lock */
} else {
    echo "Couldn't get the lock"; 
}

However, if I put the same code inside a session, it fails on my live site, but 
still works fine in my localhost (version 5.3.8):

session_start();
echo "<br>Flock Test With Session<br>"; 
$fp = fopen("_order_id.txt", "r+");
if (flock($fp, LOCK_EX)) { 
    /* do an exclusive lock to get an order number */
    $id = fread($fp,filesize("_order_id.txt"));
    $id++;
    echo "<br>Got the lock, id is now $id";
    ftruncate($fp, 0); /* truncate file */
    rewind($fp); /* reset pointer */
    fwrite($fp, $id); /* write new order id */
    flock($fp, LOCK_UN); /* release the lock */
} else {
    echo "Couldn't get the lock"; 
}
session_destroy();
 [2013-06-27 09:33 UTC] yohgaki@php.net
-Status: Open +Status: Feedback
 [2013-06-27 09:33 UTC] yohgaki@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.4-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

I really don't have clue why you had such problem with 5.2.9.
May be suexec thing.

Please try 5.5 or 5.4.
 [2013-06-27 09:37 UTC] yohgaki@php.net
If you are executing multiple php scripts (e.g. iframe, css, js, etc executes 
php) 

You are better call session_write_close() in your script ASAP.
 [2013-10-15 11:54 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.
 
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Tue Jan 31 21:05:54 2023 UTC