Bug #51431 [Opn]: Problem with method_exists and autoloader

[email protected] Wed, 31 Mar 2010 10:46:25 +0200 (CEST)
Newsgroups php.bugs
Message-ID <[email protected]>
Edit report at http://bugs.php.net/bug.php?id=51431&edit=1

 ID:               51431
 Updated by:       [email protected]
 Reported by:      mboland at internl dot net
 Summary:          Problem with method_exists and autoloader
 Status:           Open
 Type:             Bug
 Package:          Reproducible crash
 Operating System: Linux
 PHP Version:      5.2SVN-2010-03-29 (snap)

 New Comment:

Does this also happens on 5.3SVN?


Previous Comments:
------------------------------------------------------------------------
[2010-03-29 21:12:53] mboland at internl dot net

Bugs that are caused by a problem similar to this:-
#50360
#46753

------------------------------------------------------------------------
[2010-03-29 21:11:00] mboland at internl dot net

Forgot to mention: the test script crashes with a segmentation fault.
The PHP used was built with
./configure --enable-debug

------------------------------------------------------------------------
[2010-03-29 21:07:16] mboland at internl dot net

Description:
------------
A call to method_exists may invoke a class loader. If the class loader
is complicated enough, PHP will reallocate the stack to make more room.
Once the class loader returns, PHP will then dereference a variable that
is no longer valid.


Test script:
---------------
<?php
    function recurse($i) {
        if ($i > 0) {
            recurse($i - 1);
        } else {
            class C { }
        }
    }
    function autoload_function($unused) {
        recurse(17);
    }
    spl_autoload_register('autoload_function');
    method_exists('C', 'foo');


Actual result:
--------------
$ gdb --args ./sapi/cli/php crash.php
GNU gdb (GDB) 7.0-ubuntu
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show
copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from
/home/mboland/src/php5.2-201003291630/sapi/cli/php...done.
(gdb) break zif_method_exists 
Breakpoint 1 at 0x832a702: file
/home/mboland/src/php5.2-201003291630/Zend/zend_builtin_functions.c,
line 898.
(gdb) r
Starting program: /home/mboland/src/php5.2-201003291630/sapi/cli/php
crash.php
[Thread debugging using libthread_db enabled]

Breakpoint 1, zif_method_exists (ht=2, return_value=0x854e124, 
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at
/home/mboland/src/php5.2-201003291630/Zend/zend_builtin_functions.c:898
898             if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2,
&klass, &method_name)==FAILURE) {
(gdb) n
901             if (Z_TYPE_PP(klass) == IS_OBJECT) {
(gdb) print method_name 
$1 = (zval **) 0x854344c
(gdb) print *method_name
$2 = (zval *) 0x854b6e4
(gdb) print *method_name
$3 = {value = {lval = 139780340, dval = 6.435048036853826e-314, str = {
      val = 0x854e0f4 "foo", len = 3}, ht = 0x854e0f4, obj = {
      handle = 139780340, handlers = 0x3}}, refcount = 1, type = 6
'\006', 
  is_ref = 0 '\000'}
(gdb) watch *method_name 
Hardware watchpoint 2: *method_name
(gdb) c
Continuing.
Hardware watchpoint 2: *method_name

Old value = (zval *) 0x854b6e4
New value = (zval *) 0x5a5a5a5a
memset () at ../sysdeps/i386/i686/memset.S:85
85      ../sysdeps/i386/i686/memset.S: No such file or directory.
        in ../sysdeps/i386/i686/memset.S
Current language:  auto
The current source language is "auto; currently asm".
(gdb) bt
#0  memset () at ../sysdeps/i386/i686/memset.S:85
#1  0x082fc11c in _zend_mm_free_int (heap=0x848a1d8, p=0x8543444, 
    __zend_filename=0x845db80
"/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h",
__zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:1952
#2  0x082fcdd0 in _zend_mm_realloc_int (heap=0x848a1d8, p=0x8543444,
size=520, 
    __zend_filename=0x845db80
"/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h",
__zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:2237
#3  0x082fd040 in _erealloc (ptr=0x8543444, size=520, allow_failure=0, 
    __zend_filename=0x845db80
"/home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h",
__zend_lineno=73, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_alloc.c:2321
#4  0x0833ca69 in zend_ptr_stack_2_push (stack=0x8489580, a=0x1, b=0x0)
    at /home/mboland/src/php5.2-201003291630/Zend/zend_ptr_stack.h:73



------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=51431&edit=1