Hello. There are two bugs that show when code is executed from an object destructor and PHP is compiled in debug mode. Both bugs cause the zend_hash_find() to fail in the IS_CONSISTENT() macro.
The first bug shows when the global symtable is destroyed and the destruction of a symbol causes an object destruction. If the object destructor tries to access a global symbol the zend_hash_find, IS_CONSISTENT() check will fail and error message will be logged. Here is code that shows the bug: <? class lala { public function __destruct () { global $abc; printf ("%s\n", $abc); } } $obj = new lala (); $abc = "123"; ?> The second bug shows when the object properties hash is destroyed. If the destruction of some property causes a destructor of a second object to be called and that destructor tries to access aproperty of the first object being destroyed zend_hash_find() will fail for the same reason as in first bug. Here is sample code: <? class A { private $objref; public $val; public function __construct () { $this->obref = new B (); $this->val = "msg"; } } class B { public function __destruct () { global $gA; printf ("%s\n", $gA->val); } } $gA = new A (); ?> And here is a patch that fixes these two bugs: diff -ruN php5-200310182330.orig/Zend/zend_execute_API.c php5-200310182330/Zend/zend_execute_API.c --- php5-200310182330.orig/Zend/zend_execute_API.c 2003-10-14 15:07:10.000000000 +0000 +++ php5-200310182330/Zend/zend_execute_API.c 2003-10-22 09:10:20.000000000 +0000 @@ -207,7 +207,13 @@ */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC); - zend_hash_destroy(&EG(symbol_table)); +/* We need to use graceful destroy here because of the following problem when + Zend engine iscompiled in debug mode. Suppose the destruction of the + symtable causes the destruction of some object. If the destructor of that + object tries to access some global variable, it will fail because the + symtable hash is in inconsistent state and Zend engine will bail out in + IS_CONSISTENT() */ + zend_hash_graceful_destroy(&EG(symbol_table)); } zend_end_try(); zend_try { diff -ruN php5-200310182330.orig/Zend/zend_objects.c php5-200310182330/Zend/zend_objects.c --- php5-200310182330.orig/Zend/zend_objects.c 2003-09-02 15:06:33.000000000 +0000 +++ php5-200310182330/Zend/zend_objects.c 2003-10-22 09:13:02.000000000 +0000 @@ -26,7 +26,13 @@ static inline void zend_nuke_object(zend_object *object TSRMLS_DC) { - zend_hash_destroy(object->properties); +/* We need to use graceful destroy here because of the following problem when + Zend engine is compiled in debug mode. Suppose the destruction of some + property invokes a destructor which possibly calls other functions and + that call chain at some place tries to access a property of the nuked + object. The access will fail because the properties hash is in + inconsistent state and Zend engine will bail out in IS_CONSISTENT () */ + zend_hash_graceful_destroy(object->properties); FREE_HASHTABLE(object->properties); efree(object); } -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php