php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36647 __get and foreach / Segfaults
Submitted: 2006-03-07 17:41 UTC Modified: 2006-08-01 22:48 UTC
Votes:4
Avg. Score:5.0 ± 0.0
Reproduced:3 of 4 (75.0%)
Same Version:0 (0.0%)
Same OS:1 (33.3%)
From: pumuckel at metropolis dot de Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS-2006-03-07 (snap) OS: Linux
Private report: No CVE-ID: None
 [2006-03-07 17:41 UTC] pumuckel at metropolis dot de
Description:
------------
Hello,

we currently monitor segmentation faults on all of our production and development servers running php 5.0.5 and 5.1.2 which leads to a complete application failure. 

We traced down the problem to be associated with a foreach loop over an array return by __get method within a class.

The segmentation fault occurs randomly either while shutting down php module (while cleaning up memory) or just within the application after the foreach loop.

Using the current snapshot the problem can be reproduced visually (without segfaults) as follows: See Reproduce code

I think the foreach within the X function in conjunction with the $bar variable is freeing $t->errors array, which in fact is wrong behaviour. Using $bar var as input for the foreach makes the application working, too.

Note that this small application does not segfault, but when executing some (a lot) just before and after that code sniplet it almost always leads to a crash here.

Who is able to look at that and provide a patch?

Thank you,

 Mike 

Reproduce code:
---------------
<?
 class Foo {
   private $data = array("errors" => array(1, 2, 3));
   function __get($x) {
     return $this->data[$x];
   }
 }

 $t = new Foo();
 var_dump($t);

 function X(Foo $t) { // when using the foreach within a function the error gets triggered
   // following 2 lines have to be enabled to see the bug.
   $bar = $t->errors;  // not using this line makes the script working.
   foreach($t->errors as $foo);  // not using this line also makes the script working.
 }

 X($t);
 var_dump($t);
?>

Expected result:
----------------
object(Foo)#4 (1) {
 ["data:private"]=>
 array(1) {
   ["errors"]=>
   array(3) {
     [0]=>
     int(1)
     [1]=>
     int(2)
     [2]=>
     int(3)
   }
 }
}
object(Foo)#4 (1) {
 ["data:private"]=>
 array(1) {
   ["errors"]=>
   array(3) {
     [0]=>
     int(1)
     [1]=>
     int(2)
     [2]=>
     int(3)
   }
 }
}


Actual result:
--------------
object(Foo)#4 (1) {
 ["data:private"]=>
 array(1) {
   ["errors"]=>
   array(3) {
     [0]=>
     int(1)
     [1]=>
     int(2)
     [2]=>
     int(3)
   }
 }
}
object(Foo)#4 (1) {
 ["data:private"]=>
 array(1) {
   ["errors"]=>
   NULL
 }
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-07 17:48 UTC] tony2001@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 for *NIX and
http://bugs.php.net/bugs-generating-backtrace-win32.php for Win32

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.


 [2006-03-07 17:50 UTC] pumuckel at metropolis dot de
Operating System: Gentoo Linux and SuSE 8.1
PHP 5.1.3-dev (cli) (built: Mar  7 2006 15:07:07)
PHP 5.0.5 (cli) (built: Feb  2 2006 11:35:32)
and appropriate apache2 modules.

gdb backtrace of 5.1.3 php module of our application:

(gdb) backtrace
#0  _zend_hash_add_or_update (ht=0x87c652c, arKey=0xb7aafbf5 "args", nKeyLength=5, pData=0xbfffb16c, nDataSize=4, pDest=0x0, flag=1)
    at /usr/local/php5.1-200603071330/Zend/zend_hash.c:213
#1  0xb78b9124 in add_assoc_zval_ex (arg=0x0, key=0xb7aafbf5 "args", key_len=5, value=0x87c607c) at zend_hash.h:331
#2  0xb78c5581 in zend_fetch_debug_backtrace (return_value=0x87c607c, skip_last=1, provide_object=1)
    at /usr/local/php5.1-200603071330/Zend/zend_builtin_functions.c:1938
#3  0xb78d1b80 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffb4a0) at zend_vm_execute.h:200
#4  0xb78d14dc in execute (op_array=0x8442a98) at zend_vm_execute.h:92
#5  0xb78d1760 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffb790) at zend_vm_execute.h:234
#6  0xb78d14dc in execute (op_array=0x8646c84) at zend_vm_execute.h:92
#7  0xb790c0f7 in ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER (execute_data=0xbfffbc50) at zend_vm_execute.h:19441
#8  0xb78d14dc in execute (op_array=0x873a45c) at zend_vm_execute.h:92
#9  0xb78d1760 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffbfa0) at zend_vm_execute.h:234
#10 0xb78d14dc in execute (op_array=0x84b0f94) at zend_vm_execute.h:92
#11 0xb78d1760 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffc3b0) at zend_vm_execute.h:234
#12 0xb78d14dc in execute (op_array=0x870b194) at zend_vm_execute.h:92
#13 0xb78d1760 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffcb20) at zend_vm_execute.h:234
#14 0xb78d14dc in execute (op_array=0x85d42fc) at zend_vm_execute.h:92
#15 0xb78d1760 in zend_do_fcall_common_helper_SPEC (execute_data=0xbfffcca0) at zend_vm_execute.h:234
#16 0xb78d14dc in execute (op_array=0x83ffb94) at zend_vm_execute.h:92
#17 0xb78b6660 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/local/php5.1-200603071330/Zend/zend.c:1109
#18 0xb787a21d in php_execute_script (primary_file=0xbfffeff0) at /usr/local/php5.1-200603071330/main/main.c:1719
#19 0xb7926d5a in php_handler (r=0x84c2920) at /usr/local/php5.1-200603071330/sapi/apache2handler/sapi_apache2.c:584
#20 0x08068a45 in ap_run_handler (r=0x84c2920) at config.c:152
#21 0x08069040 in ap_invoke_handler (r=0x84c2920) at config.c:364
#22 0x0806593a in ap_process_request (r=0x84c2920) at http_request.c:249
#23 0x08060dcd in ap_process_http_connection (c=0x83c01e8) at http_core.c:251
#24 0x08072925 in ap_run_process_connection (c=0x83c01e8) at connection.c:43
#25 0x08067044 in child_main (child_num_arg=0) at prefork.c:610
#26 0x08067197 in make_child (s=0x0, slot=0) at prefork.c:704
#27 0x08067429 in perform_idle_server_maintenance (p=0x80a2e28) at prefork.c:839
#28 0x08067b15 in ap_mpm_run (_pconf=0x0, plog=0x80cced0, s=0x0) at prefork.c:1040
#29 0x0806e0ad in main (argc=5, argv=0xbffff434) at main.c:618


gdb bt of 5.0.5 php module looks a lot different.
 [2006-03-07 17:56 UTC] tony2001@php.net
Dmitry, please look into it.
 [2006-03-23 01:16 UTC] judas dot iscariote at gmail dot com
This test also leaks memory..

/local/local/bodegon/php-debug/Zend/zend_hash.c(764) :  Freeing 0x00A1D3A0 (71 bytes), script=foreach.php
/local/local/bodegon/php-debug/Zend/zend_hash.c(383) : Actual location (location was relayed)
Last leak repeated 2 times
[Wed Mar 22 20:16:04 2006]  Script:  'foreach.php'
/local/local/bodegon/php-debug/Zend/zend_variables.c(133) :  Freeing 0x00A1D090 (64 bytes), script=foreach.php
/local/local/bodegon/php-debug/Zend/zend_hash.c(169) : Actual location (location was relayed)
[Wed Mar 22 20:16:04 2006]  Script:  'foreach.php'
/local/local/bodegon/php-debug/Zend/zend_variables.h(45) :  Freeing 0x00A1CFF0 (72 bytes), script=foreach.php
/local/local/bodegon/php-debug/Zend/zend_variables.c(132) : Actual location (location was relayed)
[Wed Mar 22 20:16:04 2006]  Script:  'foreach.php'
/local/local/bodegon/php-debug/Zend/zend_vm_execute.h(7460) :  Freeing 0x00A1CAA0 (24 bytes), script=foreach.php
[Wed Mar 22 20:16:04 2006]  Script:  'foreach.php'
/local/local/bodegon/php-debug/Zend/zend_compile.c(3208) :  Freeing 0x00A139D0 (24 bytes), script=foreach.php
Last leak repeated 2 times
=== Total 9 memory leaks detected ===
 [2006-08-01 22:48 UTC] tony2001@php.net
Not reproducible with 5.2-CVS.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Tue Mar 02 12:01:23 2021 UTC