mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fixed bug #45434 (circular reference causes segfault in gc_collect_cycles())
This commit is contained in:
parent
8d2e0a7e0f
commit
0ab4c933e7
3 changed files with 28 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
|||
--TEST--
|
||||
GC 028: GC and destructors
|
||||
GC 029: GC and destructors
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
|
|
21
Zend/tests/gc_030.phpt
Normal file
21
Zend/tests/gc_030.phpt
Normal file
|
@ -0,0 +1,21 @@
|
|||
--TEST--
|
||||
GC 030: GC and exceptions in destructors
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
public $foo;
|
||||
|
||||
public function __destruct() {
|
||||
throw new Exception("foobar");
|
||||
}
|
||||
}
|
||||
|
||||
$f1 = new foo;
|
||||
$f2 = new foo;
|
||||
$f1->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
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue