mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
Merge branch 'PHP-7.0'
Conflicts: Zend/zend_vm_execute.h
This commit is contained in:
commit
a4a767e6da
7 changed files with 171 additions and 10 deletions
46
Zend/tests/bug70805.phpt
Normal file
46
Zend/tests/bug70805.phpt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #70805 (Segmentation faults whilst running Drupal 8 test suite)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class A {
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public function __destruct() {
|
||||||
|
if (isset($GLOBALS["a"])) {
|
||||||
|
unset($GLOBALS["array"]);
|
||||||
|
unset($GLOBALS["a"]); // this will be called in gc_colloct_roots and put $a into gc roots buf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = new A;
|
||||||
|
$a->b = new B;
|
||||||
|
$a->b->a = $a;
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
$c = new A;
|
||||||
|
$array = array($c); //This is used to leave a room for $GLOBALS["a"]
|
||||||
|
unset($c);
|
||||||
|
|
||||||
|
while ($i++ < 9997) {
|
||||||
|
$t = [];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t);
|
||||||
|
}
|
||||||
|
$t = [new C];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t); // This is used to trigger C::__destruct while doing gc_colloct_roots
|
||||||
|
|
||||||
|
$e = $a;
|
||||||
|
unset($a); // This one can not be putted into roots buf because it's full, thus gc_colloct_roots will be called,
|
||||||
|
// but C::__destructor which is called in gc_colloct_roots will put $a into buf
|
||||||
|
// which will make $a be putted into gc roots buf twice
|
||||||
|
var_dump(gc_collect_cycles());
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(0)
|
43
Zend/tests/bug70805_1.phpt
Normal file
43
Zend/tests/bug70805_1.phpt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #70805 (Segmentation faults whilst running Drupal 8 test suite) (Crash)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class A {
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public function __destruct() {
|
||||||
|
if (isset($GLOBALS["a"])) {
|
||||||
|
unset($GLOBALS["array"]);
|
||||||
|
unset($GLOBALS["a"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = new A;
|
||||||
|
$a->b = new B;
|
||||||
|
$a->b->a = $a;
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
$c = new A;
|
||||||
|
$array = array($c);
|
||||||
|
unset($c);
|
||||||
|
|
||||||
|
while ($i++ < 9997) {
|
||||||
|
$t = [];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t);
|
||||||
|
}
|
||||||
|
$t = [new C];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t);
|
||||||
|
unset($a);
|
||||||
|
|
||||||
|
var_dump(gc_collect_cycles());
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
int(2)
|
37
Zend/tests/bug70805_2.phpt
Normal file
37
Zend/tests/bug70805_2.phpt
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #70805 (Segmentation faults whilst running Drupal 8 test suite) (Memleak)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class A {
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public function __destruct() {
|
||||||
|
if (isset($GLOBALS["a"])) {
|
||||||
|
unset($GLOBALS["a"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = new A;
|
||||||
|
$a->b = new B;
|
||||||
|
$a->b->a = $a;
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
while ($i++ < 9998) {
|
||||||
|
$t = [];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t);
|
||||||
|
}
|
||||||
|
$t = [new C];
|
||||||
|
$t[] = &$t;
|
||||||
|
unset($t);
|
||||||
|
|
||||||
|
unset($a);
|
||||||
|
var_dump(gc_collect_cycles());
|
||||||
|
--EXPECT--
|
||||||
|
int(2)
|
|
@ -242,6 +242,13 @@ ZEND_API void ZEND_FASTCALL gc_possible_root(zend_refcounted *ref)
|
||||||
GC_REFCOUNT(ref)++;
|
GC_REFCOUNT(ref)++;
|
||||||
gc_collect_cycles();
|
gc_collect_cycles();
|
||||||
GC_REFCOUNT(ref)--;
|
GC_REFCOUNT(ref)--;
|
||||||
|
if (UNEXPECTED(GC_REFCOUNT(ref)) == 0) {
|
||||||
|
zval_dtor_func_for_ptr(ref);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (UNEXPECTED(GC_INFO(ref))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
newRoot = GC_G(unused);
|
newRoot = GC_G(unused);
|
||||||
if (!newRoot) {
|
if (!newRoot) {
|
||||||
#if ZEND_GC_DEBUG
|
#if ZEND_GC_DEBUG
|
||||||
|
|
|
@ -1049,9 +1049,13 @@ ZEND_API int ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string *key)
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
} else {
|
} else {
|
||||||
if (ht->pDestructor) {
|
if (ht->pDestructor) {
|
||||||
ht->pDestructor(data);
|
zval tmp;
|
||||||
}
|
ZVAL_COPY_VALUE(&tmp, data);
|
||||||
ZVAL_UNDEF(data);
|
ZVAL_UNDEF(data);
|
||||||
|
ht->pDestructor(&tmp);
|
||||||
|
} else {
|
||||||
|
ZVAL_UNDEF(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_zend_hash_del_el_ex(ht, idx, p, prev);
|
_zend_hash_del_el_ex(ht, idx, p, prev);
|
||||||
|
|
|
@ -5605,8 +5605,14 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
zval_dtor_func_for_ptr(garbage);
|
zval_dtor_func_for_ptr(garbage);
|
||||||
} else {
|
} else {
|
||||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
|
zval *z = var;
|
||||||
|
ZVAL_DEREF(z);
|
||||||
|
if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
gc_possible_root(Z_COUNTED_P(z));
|
||||||
|
} else {
|
||||||
|
ZVAL_UNDEF(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
|
|
@ -7737,8 +7737,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
zval_dtor_func_for_ptr(garbage);
|
zval_dtor_func_for_ptr(garbage);
|
||||||
} else {
|
} else {
|
||||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
|
zval *z = var;
|
||||||
|
ZVAL_DEREF(z);
|
||||||
|
if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
gc_possible_root(Z_COUNTED_P(z));
|
||||||
|
} else {
|
||||||
|
ZVAL_UNDEF(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
@ -35008,8 +35014,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
zval_dtor_func_for_ptr(garbage);
|
zval_dtor_func_for_ptr(garbage);
|
||||||
} else {
|
} else {
|
||||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
|
zval *z = var;
|
||||||
|
ZVAL_DEREF(z);
|
||||||
|
if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
gc_possible_root(Z_COUNTED_P(z));
|
||||||
|
} else {
|
||||||
|
ZVAL_UNDEF(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
@ -43180,8 +43192,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
zval_dtor_func_for_ptr(garbage);
|
zval_dtor_func_for_ptr(garbage);
|
||||||
} else {
|
} else {
|
||||||
GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
|
zval *z = var;
|
||||||
|
ZVAL_DEREF(z);
|
||||||
|
if (Z_COLLECTABLE_P(z) && UNEXPECTED(!Z_GC_INFO_P(z))) {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
gc_possible_root(Z_COUNTED_P(z));
|
||||||
|
} else {
|
||||||
|
ZVAL_UNDEF(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZVAL_UNDEF(var);
|
ZVAL_UNDEF(var);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue