| Bug #38962 | memory leak in fgets when using cli | ||||
|---|---|---|---|---|---|
| Submitted: | 26 Sep 2006 2:57pm UTC | Modified: | 23 Nov 12:54pm UTC | ||
| From: | jim-bo at hotpop dot com | Assigned to: | |||
| Status: | Wont fix | Category: | Documentation problem | ||
| Version: | 5.2.5 | OS: | Linux Debian Lenny | ||
| Votes: | 2 | Avg. Score: | 3.0 ± 0.0 | Reproduced: | 2 of 2 (100.0%) |
| Same Version: | 1 (50.0%) | Same OS: | 1 (50.0%) | ||
[26 Sep 2006 3:27pm UTC] tony2001@php.net
What you see is not a leak (a leak would be reported to you by the memory manager), this how memory manager work. No bug here.
[9 Dec 2008 3:23pm UTC] mfischer@php.net
I've just experienced the Problem myself, but on 5.2.5 (updated version/Distribution). I'm reopening it as a Documentation Problem then, when this is expected. http://us.php.net/fgets doesn't say it can possibly leak and stream_get_line() should be used instead, so if that's the way it works it should be documented (or someone steps up and considers this fixable?).
[16 Sep 6:06am UTC] torben@php.net
I can replicate this using PHP 5.2.6 but not 5.2.11RC2-dev or 5.3.2-dev. If anybody can tell me when this was actually fixed I'll add a changelog note in the docs for it. Otherwise this bug should be closed. Just for the record, I can only replicate on 5.2.6 when using the optional length parameter; leaving it out caused the problem to go away.
[23 Nov 12:53pm UTC] vrana@php.net
PHP manual doesn't document PHP internals.

Description: ------------ Using cli on debian etch it seems that fgets leaks memory. I have replaced fgets with stream_get_line and it seems to not leak. Please forgive me if this is a programming error on my behalf...but i can't see it. PHP 5.1.6-1 (cli) (built: Sep 1 2006 13:52:26) Copyright (c) 1997-2006 The PHP Group Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies Reproduce code: --------------- <? $descriptorSpec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child process will read from 1 => array("pipe", "w"), // stdout is a pipe that the child process will write to 2 => array("pipe", "w") // stderr is a pipe that the child process will write to ); for ($i=0;$i<20;++$i) { $process = proc_open('/usr/bin/uptime', $descriptorSpec, $pipes); if (is_resource($process)) { fclose($pipes[0]); while(!feof($pipes[1])) $stdout .= fgets($pipes[1], 1024); fclose($pipes[1]); fclose($pipes[2]); } $returnValue = proc_close($process); unset($returnValue, $stdout, $stderr, $process, $pipes[0], $pipes[1], $pipes[2]); print $i . ' ==> ' . memory_get_usage() . "\r\n"; } ?> Expected result: ---------------- 0 ==> 41344 1 ==> 41408 2 ==> 41408 3 ==> 41408 4 ==> 41408 5 ==> 41408 6 ==> 41408 7 ==> 41408 8 ==> 41408 9 ==> 41408 10 ==> 41408 11 ==> 41408 12 ==> 41408 13 ==> 41408 14 ==> 41408 15 ==> 41408 16 ==> 41408 17 ==> 41408 18 ==> 41408 19 ==> 41408 (this is the actual result when replacing fgets with stream_get_line) Actual result: -------------- 0 ==> 41240 1 ==> 41368 2 ==> 41432 3 ==> 41496 4 ==> 41560 5 ==> 41624 6 ==> 41688 7 ==> 41752 8 ==> 41816 9 ==> 41880 10 ==> 41944 11 ==> 42008 12 ==> 42072 13 ==> 42136 14 ==> 42200 15 ==> 42264 16 ==> 42328 17 ==> 42392 18 ==> 42456 19 ==> 42520