Bug #74802 [Opn->Dup]: Bogus detection of values capture in destructors within garbage collector
| From: | nikic@php.net | Date: | Fri, 23 Jun 2017 08:58:23 +0000 |
| Subject: | Bug #74802 [Opn->Dup]: Bogus detection of values capture in destructors within garbage collector | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-209639@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74802&edit=1
ID: 74802
Updated by: nikic@php.net
Reported by: bwoebi@php.net
Summary: Bogus detection of values capture in destructors
within garbage collector
-Status: Open
+Status: Duplicate
Type: Bug
Package: Reproducible crash
Operating System: Irrelevant
PHP Version: master-Git-2017-06-23 (Git)
Block user comment: N
Private report: N
New Comment:
Duplicate of bug #72530.
Previous Comments:
------------------------------------------------------------------------
[2017-06-23 02:45:00] bwoebi@php.net
Description:
------------
Our current logic in garbage collector assumes that, if we have a refcount not higher than before,
the data can be safely freed.
Which is not a valid assumption as the following snippet demonstrates: if the value is incremented
by backing up and decremented again by manual unset(), the refcount is still equal; thus the garbage
collector will free it, even though it cannot.
The relevant snippet within zend_gc.c, after invoking destructors, on each remaining root:
if (GC_REFCOUNT(current->ref) > current->refcount) {
gc_remove_nested_data_from_buffer(current->ref, current);
}
Test script:
---------------
(function() {
$foo = new class {
public $bar;
function __destruct() {
global $bak;
$bak = $this->bar;
unset($this->bar); // do not fulfil the condition
}
};
$bar = new stdClass;
$bar->foo = $foo;
$foo->bar = $bar;
})();
gc_collect_cycles();
var_dump($bak);
Expected result:
----------------
object(stdClass)#3 (1) {
["foo"]=>
object(class@anonymous)#2 (1) {
["bar"]=>
*RECURSION*
}
}
Actual result:
--------------
Segmentation fault (or at least valgrind warning)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74802&edit=1