php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #31742 print_r tries to allocate 1.5gb RAM and fails, corrupt array/hash?
Submitted: 2005-01-28 16:07 UTC Modified: 2005-02-11 08:18 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: frode at coretrek dot no Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 4CVS-2005-01-28 (PHP_4_3 only!) OS: FreeBSD 4.10
Private report: No CVE-ID: None
 [2005-01-28 16:07 UTC] frode at coretrek dot no
Description:
------------
I've been having problems with ridiculous "out of memory" errors caused by print_r trying to allocate about 1.5gb of memory while printing an object where one of the object fields is an array of objects. It appears the array is completely corrupted. 

Unfortunately I'm not at liberty to provide the full source code of our application, and I've been unable to reduce the reproducible crash down to a simple test case - it only occurs when all mysql queries, session handling etc. are left in place.

However, I've been playing around with gdb on a debug-build of today's PHP4 snapshot. I set a breakpoint on "zend.c:201", which is the beginning of "zend_print_zval_ex()". Each time this breakpoint is reached, "*expr" contains the various strings which are fields of the object in question. But just before PHP exits with an out-of-memory error, the following is reached instead of printing the field which contains an array of other objects:

--- (gdb breakpoint backtrace and *expr display) --------
Breakpoint 1, zend_print_zval_ex (write_func=0x2848fa1c <php_body_write_wrapper>, expr=0x81af164, indent=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:201
201             zend_make_printable_zval(expr, &expr_copy, &use_copy);
1: *expr = {value = {lval = 1515870810, dval = 1.7838867517321418e+127, str = {val = 0x5a5a5a5a <Error reading address 0x5a5a5a5a: Bad address>, len = 1515870810}, ht = 0x5a5a5a5a, obj = {
      ce = 0x5a5a5a5a, properties = 0x5a5a5a5a}}, type = 90 'Z', is_ref = 90 'Z', refcount = 23131}

(gdb) bt
#0  zend_print_zval_ex (write_func=0x2848fa1c <php_body_write_wrapper>, expr=0x81af164, indent=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:201
#1  0x284c451c in zend_print_zval (expr=0x81af164, indent=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:192
#2  0x284c3fbc in zend_print_variable (var=0x81af164) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend_variables.c:151
#3  0x284c4738 in zend_print_zval_r_ex (write_func=0x2848fa1c <php_body_write_wrapper>, expr=0x81af164, indent=8) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:253
#4  0x284c45ec in zend_print_zval_r (expr=0x81af164, indent=8) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:221
#5  0x284c422f in print_hash (ht=0x88009a4, indent=4) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:130
#6  0x284c471b in zend_print_zval_r_ex (write_func=0x2848fa1c <php_body_write_wrapper>, expr=0x8806824, indent=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:248
#7  0x284c45ec in zend_print_zval_r (expr=0x8806824, indent=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:221
#8  0x28417509 in zif_print_r (ht=1, return_value=0x87d93a4, this_ptr=0x0, return_value_used=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/ext/standard/basic_functions.c:2565
#9  0x284d882f in execute (op_array=0x819a500) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend_execute.c:1652
#10 0x284d8a2c in execute (op_array=0x85f7d24) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend_execute.c:1696
#11 0x284da8ab in execute (op_array=0x813daa4) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend_execute.c:2222
#12 0x284da8ab in execute (op_array=0x813d824) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend_execute.c:2222
#13 0x284c5715 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/Zend/zend.c:926
#14 0x28490f47 in php_execute_script (primary_file=0xbfbff388) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/main/main.c:1739
#15 0x284dd742 in apache_php_module_main (r=0x812f038, display_source_mode=0) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/sapi/apache/sapi_apache.c:54
#16 0x284de45e in send_php (r=0x812f038, display_source_mode=0, filename=0x8130fc0 "/home/frode/public_html/devel/corepublish/CorePublish/html/article_save.php")
    at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/sapi/apache/mod_php4.c:621
#17 0x284de4b6 in send_parsed_php (r=0x812f038) at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/sapi/apache/mod_php4.c:636
#18 0x8053c10 in ap_invoke_handler ()
#19 0x8063e35 in process_request_internal ()
#20 0x8063e94 in ap_process_request ()
#21 0x805d1a6 in child_main ()
#22 0x805d338 in make_child ()
#23 0x805d455 in startup_children ()
#24 0x805d9a8 in standalone_main ()
#25 0x805e0a7 in main ()
#26 0x804fd0e in _start ()
--- (gdb breakpoint backtrace and *expr display) --------


Note that the str "val" is 0x5a5a5a5a, or 'ZZZZ' in ascii. The type is also 'Z', as well as other fields of zval. The str.len is shown as 1515870810, which is the exact number of bytes in the out-of-memory message found in the apache log:


--- (apache error log) -----------
[Fri Jan 28 15:45:42 2005] [error] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/main/output.c:394 (tried to allocate 1515837440 bytes) in /home/frode/public_html/devel/corepublish/CorePublish/include/common-functions.php on line 762
Allowed memory size of 134217728 bytes exhausted at /home/frode/temp/apdeb/src/php4-STABLE-200501281330/main/output.c:231 (tried to allocate 2004 bytes)
--- (apache error log) -----------

If the print_r is changed to "echo gettype($object->theArrayField)", "Unknown type" is produced. So it appears there is a case of memory corruption where lots of 'ZZZZZZZ' is dumped where the array should have been.

Do you have any ideas on tracking down this bug? Any suggestions on how to work with gdb or whatever are appreciated. 

I tried putting in a "watch 0x81af164" in gdb on startup, but that just resulted in gdb taking 100% cpu for 3 minutes and then crashing in libc's select(). 

We *did* find one workaround, but it's not really satisfactory since it's "black magic". The method that assigns the array-of-objects to the main object's field (i.e. the field that is corrupted) works like this:
  function setTheField() {
         return include("path/to/a/file/containing/the/body/of/this/method.php");
  }

When changed to:
  function setTheField() {
         include("path/to/a/file/containing/the/body/of/this/method.php");
  }

the error does not occur. But according to the PHP manual, "return include" is the correct way to return the include-file's return value as the function's return value.
Also, I'm guessing the real error is still present, but doesn't trigger because, by chance, some other memory location is corrupted instead.



Reproduce code:
---------------
N/A

Expected result:
----------------
N/A

Actual result:
--------------
N/A

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-01-31 22:24 UTC] sniper@php.net
Please try using this CVS snapshot:

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


 [2005-02-01 09:26 UTC] frode at coretrek dot no
OK, I grabbed the http://snaps.php.net/php5-latest.tar.gz file and compiled, changed all 'php4' references to 'php5' in httpd.conf and started up apache in gdb again. 

With this version of PHP, our application won't run at all. I get an error "Cannot reassign $this in XXX on line YYY ". The source code referred from that error message looks like this (in the middle of a class)

function printHtml() { 
   $asw =& $this;       <- line with error
   ..
}

This occured in three different files. By changing all places into "$asw = $this" (no '&'), I got things running fine. (Isn't assignment of objects by-ref by default in php5 anyway?)

My code seems to work fine in both the PHP5 snapshot of today, and in PHP-5.0.3. (I didn't have to remove the '&' to get things to run in PHP-5.0.3).

I guess this means this is a php4 only bug (either that, or php5 is different enough so that the bug is not visible in this particular case).

What's the next step? :)
 [2005-02-06 07:03 UTC] sniper@php.net
Please don't put such huge backtraces in the bug report, instead, put them online somewhere and paste the URL here.

I deleted the one huge comment of yours, it can be viewed still in the mailing list archives, so don't readd it here..

 [2005-02-10 15:01 UTC] sniper@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try to avoid embedding huge scripts into the report.


 [2005-02-10 15:12 UTC] frode at coretrek dot no
I'm unable to produce a simple test case, because the bug only appears with the right combination of database calls and when all the classes in our application are include()'d (I'm guessing about 100+ classes are in use, spread over ~500 files). Unfortunately, I'm not at liberty to provide the source code. 

I understand this complicates debugging a lot, but I can run GDB traces and compile debug versions of PHP with any patches/changes you might suggest, or anything else you might want, and post back the results. 

Hope to hear from you soon!
 [2005-02-11 05:07 UTC] sniper@php.net
We can't fix what we can't test..

 [2005-02-11 08:18 UTC] frode at coretrek dot no
Well, I've given you backtraces which perhaps can point to parts of the code which may or may not contain a reference-counting bug, and I think it's a shame a data-corrupting bug like this will go unfixed. Again, if you have any suggestions, I'm willing to try them out in GDB or whatever, and we can work together to nail this crasher down :)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Sep 18 22:01:26 2024 UTC