From: Dmitry Stogov Date: Tue, 8 Jul 2008 08:16:18 +0000 (+0000) Subject: Fixed bug #45434 (circular reference causes segfault in gc_collect_cycles()) X-Git-Tag: BEFORE_HEAD_NS_CHANGE~1347 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0ab4c933e7883e1fa03e799fdf6df565ea8d4278;p=php Fixed bug #45434 (circular reference causes segfault in gc_collect_cycles()) --- diff --git a/Zend/tests/gc_029.phpt b/Zend/tests/gc_029.phpt index 12f40c18c9..ea0660eca4 100644 --- a/Zend/tests/gc_029.phpt +++ b/Zend/tests/gc_029.phpt @@ -1,5 +1,5 @@ --TEST-- -GC 028: GC and destructors +GC 029: GC and destructors --FILE-- foo = $f2; +$f2->foo = $f1; +unset($f1, $f2); +gc_collect_cycles(); +?> +--EXPECTF-- +Fatal error: Ignoring exception from foo::__destruct() while an exception is already active (Uncaught Exception in %sgc_030.php on line %d) in %sgc_030.php on line %d diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index c806952ccf..59ec410ef4 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -553,9 +553,9 @@ ZEND_API int gc_collect_cycles(TSRMLS_D) !EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called) { EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].destructor_called = 1; - zend_try { - EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor(EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.object, Z_OBJ_HANDLE(p->z) TSRMLS_CC); - } zend_end_try(); + EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount++; + EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.dtor(EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.object, Z_OBJ_HANDLE(p->z) TSRMLS_CC); + EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount--; } } count++; @@ -571,19 +571,15 @@ ZEND_API int gc_collect_cycles(TSRMLS_D) EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].valid && EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount <= 0) { EG(objects_store).object_buckets[Z_OBJ_HANDLE(p->z)].bucket.obj.refcount = 1; - zend_try { - Z_TYPE(p->z) = IS_NULL; - zend_objects_store_del_ref_by_handle(Z_OBJ_HANDLE(p->z) TSRMLS_CC); - } zend_end_try(); + Z_TYPE(p->z) = IS_NULL; + zend_objects_store_del_ref_by_handle(Z_OBJ_HANDLE(p->z) TSRMLS_CC); } } else if (Z_TYPE(p->z) == IS_ARRAY) { Z_TYPE(p->z) = IS_NULL; zend_hash_destroy(Z_ARRVAL(p->z)); FREE_HASHTABLE(Z_ARRVAL(p->z)); } else { - zend_try { - zval_dtor(&p->z); - } zend_end_try(); + zval_dtor(&p->z); Z_TYPE(p->z) = IS_NULL; } p = GC_G(next_to_free);