Bug #78010 [Asn->Csd]: Segmentation fault during GC
| From: | nikic@php.net | Date: | Mon, 15 Jul 2019 11:50:42 +0000 |
| Subject: | Bug #78010 [Asn->Csd]: Segmentation fault during GC | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-221779@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: Assigned
+Status: Closed
Type: Bug
Package: Reproducible crash
Operating System: Debian 9 && Ubuntu 18.04
PHP Version: 7.3.5
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=193f28c7d557df887c4456d072113cc2478e1c3e
Log: Fixed bug #78010
Previous Comments:
------------------------------------------------------------------------
[2019-07-15 10:08:57] nikic@php.net
Candidate patch at https://github.com/php/php-src/pull/4414.
------------------------------------------------------------------------
[2019-07-15 09:26:58] nikic@php.net
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.
------------------------------------------------------------------------
[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.
------------------------------------------------------------------------
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