Bug #78010 [Ver->Ana]: Segmentation fault during GC
| From: | nikic@php.net | Date: | Mon, 15 Jul 2019 09:26:59 +0000 |
| Subject: | Bug #78010 [Ver->Ana]: Segmentation fault during GC | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-221773@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78010&edit=1
ID: 78010
Updated by: nikic@php.net
Reported by: valera dot ymnik at gmail dot com
Summary: Segmentation fault during GC
-Status: Verified
+Status: Analyzed
Type: Bug
Package: Reproducible crash
Operating System: Debian 9 && Ubuntu 18.04
PHP Version: 7.3.5
Block user comment: N
Private report: N
New Comment:
What I believe is happening here is the following: An object gets assigned GC address 2^20 (or a
multiple thereof), which is compressed to 0. The object is found to be part of a cycle and will at
the end of root collection be marked as black (color 0). Together these two mean that the object has
0 gc_info. During the GC destruction phase, some other object is destroyed first and recursively
destroyed our gc_info=0 object. When that happens we attempt to remove it from the root buffer, but
because gc_info=0 it looks like the object is not part of the root buffer and this is skipped,
eventually resulting in a double free.
Previous Comments:
------------------------------------------------------------------------
[2019-07-13 04:28:59] grzegorz129 at gmail dot com
After some more testing this bug seems to be introduced in 7.3.0 (or during it's stabilization
period). The 7.2.20 runs my short example without a problem while 7.3.0 crashes with a SIGSEGV.
While I'm unable to run the whole suite on 3v4l (since it uses substantial amount of resources
after all) I also verified all three master branches (normal/jit/opcache) and all of them are
crashing in the same way.
------------------------------------------------------------------------
[2019-07-13 00:00:05] grzegorz129 at gmail dot com
I simplified the reproducer and added some comments:
<?php
//gc_disable();
class foo
{
public function __construct()
{
$this->x = $this;
for ($i = 0; $i < 898; $i++) { //Will not trigger with <898
$obj = [new stdClass, new stdClass]; //This must have at least 2 elements
$this->y[] = $obj;
}
}
}
for ($i = 0; $i < 2; ++$i) { //This must run >=2 (increasing the number of elements in the
array *2 will not do)
$x = []; //This must be reset
foreach (array_fill(0, 389, 'x') as &$params) { //Will not trigger <389
$x[] = new foo;
}
}
echo "Completed\n";
Valgring output: https://zerobin.net/?ca2ef1bcab5e1b03#qc85nUSpB0Yp7oK4Bvd1hSOV3B9kybe34XmH6wvZE6o=
------------------------------------------------------------------------
[2019-07-12 20:50:21] grzegorz129 at gmail dot com
Maybe stating the obvious but putting
gc_disable() at the beginning of the script makes
the code complete. Also tested on 7.4alpha3 - the same result.
------------------------------------------------------------------------
[2019-07-12 18:50:46] nikic@php.net
Related To: Bug #78280
------------------------------------------------------------------------
[2019-07-12 16:11:17] kolja dot zuelsdorf at deinhandy dot de
We have this issue under strong suspicion to break one of our core business processes and wonder why
it was not addressed in the last bugfix releases. Is there anything we can do to help mitigate the
issue? So far we are running said process on an old (7.1) version.
Furthermore, I've confirmed that the same thing happens on 7.3.6 and 7.3.7 too.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=78010
--
Edit this bug report at https://bugs.php.net/bug.php?id=78010&edit=1