php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #21809 fclose() of socket never returns
Submitted: 2003-01-21 17:50 UTC Modified: 2003-02-15 09:14 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: syntheticrage at hotmail dot com Assigned: wez
Status: Closed Package: Sockets related
PHP Version: 4CVS-2003-02-14 (stable) OS: RedHat 7.3
Private report: No CVE-ID:
 [2003-01-21 17:50 UTC] syntheticrage at hotmail dot com
I've been writing a CLI-based script that connects to an xml wirefeed and continually reads the data with fgets() and parses it accordingly.  The script works fine, but occasionally the feed server goes down for maintenance, etc.  That in itself isnt a problem, but when the connection to the feed is lost, fgets() stalls and never times out regardless of the stream_set_timeout() usage.  I have written the following scripts to verify the problem (note that the "server" script is only to help test the fgets() bug in the "client" script).

I run this script (the "server" script) on my workstation (running XP w/ PHP 4.3.0 in CLI mode) to listen on a socket:

<?php

	error_reporting(E_ALL);
	set_time_limit(0);
	ob_implicit_flush();

	$sock = socket_create (AF_INET, SOCK_STREAM, 0);
	socket_bind($sock, "192.168.1.11", "10000");
	socket_listen($sock, 5);
	$msgsock = socket_accept($sock);
	do {
		$buf = socket_read($msgsock, 2048);
	} while (true);
	socket_close($msgsock);
	socket_close($sock);

?>

Then I run this script (the "client" script) on my linux box (running RH7.3 w/ PHP 4CVS-2003-01-20 (stable) in CLI mode) to connect to the socket:

<?php

	error_reporting(E_ALL);
	set_time_limit(30);
	ob_implicit_flush();

        $fp = fsockopen("192.168.1.10", 10000, $errno, $errstr, 10);
	if ($fp) {
		stream_set_timeout($fp, 10);
              	$data = fgets($fp);
	        $sinfo = socket_get_status($fp);
		echo ($sinfo["timed_out"]?"socket timed out\n":"eof\n");
		fclose($fp);
	} else
		echo "unable to connect\n";

?>

The client script will time-out properly when I leave the server script running.  But if I run the client script, then CTRL-C my server script, the client script never times out.  It sits at the fgets() forever, even though I've set_time_limit(30) as well as stream_set_timeout(10).

Since the script just sits there and never "crashes" to generate a corefile, I haven't been able to perform a backtrace.  Even though i've compiled PHP with --enable-debug, killing the script with CTRL-C doesn't generate a corefile (should it?).  If a bt would help, please let me know how I can generate a corefile with the CLI version of PHP.

I've configured PHP as as follows:

'./configure' '--with-apxs' '--with-config-file-path=/etc' '--with-mysql=/usr' '--with-gzip' '--with-xml' '--with-gd' '--with-zlib' '--with-freetype' '--with-ttf' '--enable-debug' 

Note that I have also verified this problem on a second linux box running RH8 w/ PHP4.3.0.  

Any help would be appreciated!

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-01-21 17:56 UTC] wez@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.

Run the cli under gdb (see instructions above),
and when it hangs press CTRL-C.
You can then type "bt" to generate the backtrace.
 [2003-01-21 17:58 UTC] wez@php.net
Are you using the 4.3.0 release or the latest stable snapshot? (the version field above and the version you mention in your comment don't seem to match up).

If you're using the released 4.3.0, please try the latest stable snapshot from snaps.php.net first.
 [2003-01-21 19:01 UTC] syntheticrage at hotmail dot com
I was using 4.3.0 on the machine running the "server" test script (but since that script is merely to aid in testing the bug in the "client" script, I didnt think it mattered).  The machine running the "client" script - the one experiencing the bug - was running a stable snapshot compiled last night.  Nontheless, I just re-compiled with the latest stable today, ran again, and managed to generate a bt in the process:

#0  0x420e19ee in select () from /lib/i686/libc.so.6
#1  0x08204844 in __DTOR_END__ ()
#2  0x08147689 in _php_stream_free (stream=0x82598fc, close_options=3)
    at /usr/local/src/php4-STABLE-200301220030/main/streams.c:327
#3  0x080c4f85 in zif_fclose (ht=1, return_value=0x8256f2c, this_ptr=0x0,
    return_value_used=0)
    at /usr/local/src/php4-STABLE-200301220030/ext/standard/file.c:1120
#4  0x08185c8b in execute (op_array=0x8254ac4)
    at /usr/local/src/php4-STABLE-200301220030/Zend/zend_execute.c:1596
#5  0x08173dcc in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/local/src/php4-STABLE-200301220030/Zend/zend.c:864
#6  0x0813c983 in php_execute_script (primary_file=0xbffffb10)
    at /usr/local/src/php4-STABLE-200301220030/main/main.c:1573
#7  0x0818c0a2 in main (argc=2, argv=0xbffffbb4)
    at /usr/local/src/php4-STABLE-200301220030/sapi/cli/php_cli.c:753
#8  0x42017589 in __libc_start_main () from /lib/i686/libc.so.6

Hope it helps :)
 [2003-01-23 03:45 UTC] wez@php.net
Could you do that again, but this time type the following after you type "bt" (also in gdb):

frame 2
print *stream
 [2003-01-23 12:38 UTC] syntheticrage at hotmail dot com
(gdb) frame 2
#2  0x08147689 in _php_stream_free (stream=0x82598fc, close_options=3)
    at /usr/local/src/php4-STABLE-200301220030/main/streams.c:327
327                     ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC);
(gdb) print *stream
$2 = {ops = 0x81ee5c0, abstract = 0x824f46c, filterhead = 0x0,
  filtertail = 0x0, wrapper = 0x0, wrapperthis = 0x0, wrapperdata = 0x0,
  fgetss_state = 0, is_persistent = 0, mode = "r+", '\0' <repeats 13 times>,
  rsrc_id = 4, in_free = 1, fclose_stdiocast = 0, stdiocast = 0x0,
  __exposed = 1, __orig_path = 0x0, context = 0x0, flags = 16, position = 0,
  readbuf = 0x8254b9c "", readbuflen = 8192, readpos = 0, writepos = 0,
  chunk_size = 8192, eof = 1}
 [2003-02-13 08:22 UTC] wez@php.net
The select call that ensures all data is flushed to the remote server never times out.
#22099 is a dup of this bug.
 [2003-02-14 15:12 UTC] sthomas at townnews dot com
I submitted bug #22099.  If it's just a duplicate of this, I'm assuming you think it's fixed.  It's not.  Here's a backtrace and I did the same thing you asked the last guy
to do by printing the contets of frame 2.  Got a really
odd result.

#0  0x401c641e in select () from /lib/libc.so.6
#1  0x0819ae24 in __DTOR_END__ ()
#2  0x08122691 in _php_stream_free (stream=0x81ead5c, close_options=3)
    at /home/install/php4-STABLE-200302141830/main/streams.c:327
#3  0x080ad213 in zif_fclose (ht=1, return_value=0x81e7a7c, this_ptr=0x0, 
    return_value_used=0)
    at /home/install/php4-STABLE-200302141830/ext/standard/file.c:1120
#4  0x0815b850 in execute (op_array=0x81da304)
    at /home/install/php4-STABLE-200302141830/Zend/zend_execute.c:1596
#5  0x08145b8c in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/install/php4-STABLE-200302141830/Zend/zend.c:864
#6  0x08118f3d in php_execute_script (primary_file=0xbffffa30)
    at /home/install/php4-STABLE-200302141830/main/main.c:1582
#7  0x08164700 in main (argc=2, argv=0xbffffad4)
    at /home/install/php4-STABLE-200302141830/sapi/cli/php_cli.c:753
#8  0x401071c4 in __libc_start_main () from /lib/libc.so.6
(gdb) frame 2
#2  0x08122691 in _php_stream_free (stream=0x81ead5c, close_options=3)
    at /home/install/php4-STABLE-200302141830/main/streams.c:327
327                     ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC);
(gdb) print *stream
Cannot access memory at address 0x0
 [2003-02-14 17:49 UTC] syntheticrage at hotmail dot com
My script still stalls.  Here's a new bt:

#0  0x420d3b2e in select () from /lib/i686/libc.so.6
#1  0x081a077c in __JCR_LIST__ ()
#2  0x0811482b in _php_stream_free (stream=0xbfffb940, close_options=3)
    at /usr/local/src/php4-STABLE-200302141830/main/streams.c:327
#3  0x080b95ee in zif_fclose (ht=1, return_value=0x81f4514, this_ptr=0x0,
    return_value_used=0)
    at /usr/local/src/php4-STABLE-200302141830/ext/standard/file.c:1120
#4  0x0813dc5a in execute (op_array=0x81ef52c)
    at /usr/local/src/php4-STABLE-200302141830/Zend/zend_execute.c:1596
#5  0x08131595 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/local/src/php4-STABLE-200302141830/Zend/zend.c:864
#6  0x0810c79c in php_execute_script (primary_file=0xbfffe1f0)
    at /usr/local/src/php4-STABLE-200302141830/main/main.c:1582
#7  0x0814255f in main (argc=2, argv=0xbfffe274)
    at /usr/local/src/php4-STABLE-200302141830/sapi/cli/php_cli.c:753
#8  0x420158d4 in __libc_start_main () from /lib/i686/libc.so.6
(gdb) frame 2
#2  0x0811482b in _php_stream_free (stream=0xbfffb940, close_options=3)
    at /usr/local/src/php4-STABLE-200302141830/main/streams.c:327
327                     ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC);
(gdb) print *stream
$1 = {ops = 0x10, abstract = 0x0, filterhead = 0x0, filtertail = 0x0,
  wrapper = 0x0, wrapperthis = 0x0, wrapperdata = 0x0, fgetss_state = 0,
  is_persistent = 0, mode = '\0' <repeats 15 times>, rsrc_id = 0, in_free = 0,
  fclose_stdiocast = 0, stdiocast = 0x0, context = 0x0, flags = 0,
  position = 0, readbuf = 0x0, readbuflen = 0, readpos = 0, writepos = 0,
  chunk_size = 0, eof = 0}
 [2003-02-15 09:14 UTC] wez@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.

The fix was not merged to the 4.3.x branch from HEAD;
it is now.
I was able to reproduce the problem and verify that this fixes it.
The next stable snapshot will have the fix.

 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 17:01:54 2014 UTC