Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.10.15

Bug #6788 backtrace memory leak
Submitted: 2006-02-15 07:30 UTC
From: touv at ouvaton dot org Assigned: cellog
Status: Closed Package: PEAR (version 1.4.6)
PHP Version: 5.1.2 OS: hp-ux
Roadmaps: (Not assigned)    
Subscription  


 [2006-02-15 07:30 UTC] touv at ouvaton dot org
Description: ------------ with php version : 5.0.5, 4.4.2, 4.3.10, 4.3.3, 4.2.3 , they are no problem, but with 5.1.1 and 5.1.2 they are un memory leak... Test script: --------------- <?php require_once('PEAR.php'); set_time_limit(0); for($i = 0; $i < 500000; $i++) { $ret = PEAR::raiseError('error'); } ?> Expected result: ---------------- nothing Actual result: -------------- <br /> <b>Fatal error</b>: Allowed memory size of 8388608 bytes exhausted (tried to allocate 40 bytes) in <b>/usr/local/apache/pear/share/pear/PEAR.php</b> on line <b>857</b><br />

Comments

 [2006-02-15 12:25 UTC] pajoye
Sorry, but your problem does not imply a bug in PEAR itself. For a list of more appropriate places to ask for help using PEAR, please visit http://pear.php.net/support/ as this bug system is not the appropriate forum for asking support questions. Thank you for your interest in PEAR. PHP Memory leaks are php bugs, not pear.
 [2006-02-15 15:50 UTC] cellog
this isn't even a memory leak, you have memory_limit enabled and set to 8M
 [2006-03-20 20:36 UTC] pz at ljseek dot com (Peter)
Hm. Why this would be bogus bug. Is it just expected tor RaiseError to accocate more and more function in its calls. The limit of 8MB is not important here - you always can have longer loop and longer running programms. If Pear developers think it is OK to leak memory this way I would appreciate if there is information outwhere on how to run long running programms with PEAR so they do not leak. At this point I've been seen similar effects with different PEAR modules - it seems like it is common approach just no to care to free memory, assuming it is used for web page creation and so you can't leak too much anyway. Currently best approach for writing long running programms with PEAR seems to be forking and killing scripts after few objects were processed so leaks do not hurt you.
 [2006-03-20 20:39 UTC] pajoye (Pierre-Alain Joye)
Follow what Toggg told you, you have to increase the memory limit in PHP.
 [2006-03-21 08:42 UTC] touv at ouvaton dot org
but if I add unset like this <?php require_once('PEAR.php'); set_time_limit(0); for($i = 9; $i < 500000; $i++) { $ret = PEAR::raiseError('error'); unset($ret); } ?> PEAR (or php, I don't know) doesn't free $ret You do not think that it is a problem ?
 [2006-03-21 09:39 UTC] pajoye (Pierre-Alain Joye)
"PEAR (or php, I don't know)" Voila, all memory operations (garbage collector included) are done by php, we (or you in your scripts) have no control on that. Check the php manual and google, there is good articles about this topic. There is no pear bug here.
 [2006-03-21 12:26 UTC] toggg (bertrand Gugger)
I did not say anything, pierre :) It's obviously a php problem. I could reproduce it with a PHP 5.1.3-dev from last month and a fresh PHP 5.1.3RC2-dev. I isolated the origin of this "memory leak". It's the call to debug_backtrace() eating up the memory. If you add before the loop in your test script: $skip = &PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); $skip = true; Then the problem disappears. This static just avoids the $this->backtrace = debug_backtrace(); in the PEAR_Error constructor. This little script crashes the same: <?php class test { var $backtrace = null; function test() { $this->backtrace = debug_backtrace(); } } set_time_limit(0); for($i = 0; $i <= 500000; $i++) { $ret = &new test(); unset($ret); } ?>
 [2006-03-24 16:02 UTC] toggg (bertrand Gugger)
I pushed it there : http://bugs.php.net/?id=36847
 [2006-04-12 12:59 UTC] toggg (bertrand Gugger)
http://bugs.php.net/?id=36847 finally comes back bogus , or at least "Documentation problem" I've put a work around there, for PEAR.php it would do: @@ -867,6 +867,7 @@ if (function_exists("debug_backtrace")) { if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { $this->backtrace = debug_backtrace(); + unset($this->backtrace[0]['object']); } } if ($mode & PEAR_ERROR_CALLBACK) { <*sighs*>
 [2006-04-12 13:15 UTC] toggg (bertrand Gugger)
and even, as we are in 4.3.0 and compat is client thing : @@ -864,10 +864,9 @@ $this->code = $code; $this->mode = $mode; $this->userinfo = $userinfo; - if (function_exists("debug_backtrace")) { - if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { - $this->backtrace = debug_backtrace(); - } + if (!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) { + $this->backtrace = debug_backtrace(); + unset($this->backtrace[0]['object']); } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE;
 [2006-04-20 17:34 UTC] toggg (bertrand Gugger)
Is there a question about that ? This self back-reference was introduced by the 5.1.x debug_backtrace(). We don't need it in the PEAR_Error object , so better withdraw it direct from our side.
 [2006-04-25 02:41 UTC] cellog (Greg Beaver)
This bug has been fixed in CVS. If this was a documentation problem, the fix will appear on pear.php.net by the end of next Sunday (CET). If this was a problem with the pear.php.net website, the change should be live shortly. Otherwise, the fix will appear in the package's next release. Thank you for the report and for helping us make PEAR better.
 [2010-02-03 05:28 UTC] steveh (Steven Hartland)
This is actually still broken in 1.9.0 and still leaks memory very badly, this is highlighted by the PayPal SDK which makes significant use of code which detects raised errors and deals with them in natural code flow i.e. not really an error case. The quick solution is to call with the parameter true e.g. debug_backtrace( true ), which prevents the object reference being set.