php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78811 Crash seen during cyclic garbage collection in Phan's unit tests
Submitted: 2019-11-14 02:41 UTC Modified: 2019-11-23 15:49 UTC
From: tandre@php.net Assigned: tandre (profile)
Status: Closed Package: Reproducible crash
PHP Version: Next Major Version OS: Linux Mint 18.3 Sylvia
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: tandre@php.net
New email:
PHP Version: OS:

 

 [2019-11-14 02:41 UTC] tandre@php.net
Description:
------------
This occurs even with a clean build. I failed to create a minimal example - it might require garbage collection at a specific time with a specific number of references to an object/closure, for all I know.

- It crashes within array_map, seemingly trying to garbage collect the object which a method is being called on and crashing.

NTS(Debug/normal) and ZTS(tried Debug) builds are having this issue for me.

Build script used: https://github.com/TysonAndre/php-src/blob/travis-debug/travis/compile.sh revision 15fb532 (`git clean -fdx` and different install folders were used)

PHP ini:

extension=ast.so
zend_extension=opcache.so
opcache.protect_memory=1
opcache.enable_cli=1
short_open_tag=0
display_errors=stderr
error_reporting=E_ALL

Script used:

# after composer.phar install on https://github.com/phan/phan/commit/1a0d7a67742d1727d12dd8556e849c72c71a4de3
USE_ZEND_ALLOC=0 gdb -args `which php` vendor/bin/phpunit --stop-on-error --stop-on-failure tests/Phan/PhanTest5.php
.....
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/tyson/php-8.0.0-debug-opcache-install/bin/php vendor/bin/phpunit tests/Phan/PhanTest5.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

WARNING: Phan is around twice as slow when php is compiled with --enable-debug (That option is only needed when debugging Phan itself).
(The above warning(s) about slow PHP settings can be disabled by setting 'skip_slow_php_options_warning' to true in .phan/config.php)
.................F.............................................  63 / 105 ( 60%)
.....F...................
Program received signal SIGSEGV, Segmentation fault.
0x0000000000aad751 in zend_gc_collect_cycles ()
    at /path/to/php-src/Zend/zend_gc.c:1562
1562                                            current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
(gdb) bt
#0  0x0000000000aad751 in zend_gc_collect_cycles ()
    at /path/to/php-src/Zend/zend_gc.c:1562
#1  0x0000000000aab370 in gc_possible_root_when_full (ref=0x7fffe8328700)
    at /path/to/php-src/Zend/zend_gc.c:592
#2  0x0000000000aab4f3 in gc_possible_root (ref=0x7fffe8328700)
    at /path/to/php-src/Zend/zend_gc.c:642
#3  0x0000000000ad516f in zend_object_release (obj=0x7fffe8328700)
    at /path/to/php-src/Zend/zend_objects_API.h:77
#4  0x0000000000b426e4 in execute_ex (ex=0x7fffeb6155e0)
    at /path/to/php-src/Zend/zend_vm_execute.h:51386
#5  0x0000000000a6133f in zend_call_function (fci=0x7fffffff9d70, fci_cache=0x7fffffff9d50)
    at /path/to/php-src/Zend/zend_execute_API.c:779
#6  0x000000000087fb1d in zif_array_map (execute_data=0x7fffeb615570, return_value=0x7fffeb615560)
    at /path/to/php-src/ext/standard/array.c:6221
#7  0x0000000000ae354e in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER ()
    at /path/to/php-src/Zend/zend_vm_execute.h:1278
#8  0x0000000000b42b0c in execute_ex (ex=0x7fffeb614020)
    at /path/to/php-src/Zend/zend_vm_execute.h:51498
#9  0x0000000000b46b39 in zend_execute (op_array=0x7fffeb672300, return_value=0x0)
    at /path/to/php-src/Zend/zend_vm_execute.h:55566
#10 0x0000000000a771e3 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /path/to/php-src/Zend/zend.c:1666
#11 0x00000000009e4a1f in php_execute_script (primary_file=0x7fffffffc570)
    at /path/to/php-src/main/main.c:2586
#12 0x0000000000b49495 in do_cli (argc=3, argv=0x186e7d0)
    at /path/to/php-src/sapi/cli/php_cli.c:959
#13 0x0000000000b4a4b5 in main (argc=3, argv=0x186e7d0)
    at /path/to/php-src/sapi/cli/php_cli.c:1350


------

Possible thoughts on why I saw this:
- ReflectionUnionType->__toString() (unlikely)
- Pre-existing issue in php 8 that got exposed due to different number of objects getting created
- Changes internally in how zend_closure objects get fetched - this was in an array_map for an instance closure.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-11-14 02:43 UTC] tandre@php.net
A few more details can be found at https://github.com/phan/phan/issues/3511
 [2019-11-15 11:25 UTC] nikic@php.net
I'm seeing

php: /home/nikic/php-src/Zend/zend_variables.c:65: zend_string_destroy: Assertion `zend_gc_refcount(&(str)->gc) == 0' failed.

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51	../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff2775801 in __GI_abort () at abort.c:79
#2  0x00007ffff276539a in __assert_fail_base (
    fmt=0x7ffff28ec7d8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0x5555566017e0 "zend_gc_refcount(&(str)->gc) == 0", file=file@entry=0x555556601728 "/home/nikic/php-src/Zend/zend_variables.c", 
    line=line@entry=65, 
    function=function@entry=0x555556601940 <__PRETTY_FUNCTION__.12241> "zend_string_destroy") at assert.c:92
#3  0x00007ffff2765412 in __GI___assert_fail (
    assertion=0x5555566017e0 "zend_gc_refcount(&(str)->gc) == 0", 
    file=0x555556601728 "/home/nikic/php-src/Zend/zend_variables.c", line=65, 
    function=0x555556601940 <__PRETTY_FUNCTION__.12241> "zend_string_destroy")
    at assert.c:101
#4  0x0000555555d4f9f0 in zend_string_destroy (str=0x55555858fe40)
    at /home/nikic/php-src/Zend/zend_variables.c:65
#5  0x0000555555d4f948 in rc_dtor_func (p=0x55555858fe40)
    at /home/nikic/php-src/Zend/zend_variables.c:57
#6  0x00000000480b323f in ?? ()
#7  0x00007fffffffa2a0 in ?? ()
#8  0x0000555555e21422 in execute_ex (ex=0x555556e566d0)
    at /home/nikic/php-src/Zend/zend_vm_execute.h:51386


with JIT only though.
 [2019-11-15 11:31 UTC] nikic@php.net
Based on JIT bisection, the miscompile is likely in PHPUnit\TextUI\ResultPrinter::formatWithColor in .../phan/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php:530.
 [2019-11-15 11:39 UTC] nikic@php.net
-Status: Open +Status: Feedback
 [2019-11-15 11:39 UTC] nikic@php.net
Can you please check whether you still see an issue after https://github.com/php/php-src/commit/bb41a1b7e70f42351b73c12b16947301c4db9cfc?

This fixes the issue I saw, but it might be distinct from yours.
 [2019-11-15 14:04 UTC] tandre@php.net
I continue to see this when running with opcache (but without JIT) after rebasing against php-src 40dcf2bd3df6a59b632220c0038cf0c4cd89eeb1.

Both NTS(non-debug) and ZTS debug are affected.

I don't see any issues when I run the ZTS --enable-debug build with opcache.jit_buffer_size=500M.

The only difference is that I see Parameter::create on top of the previous stack trace

0 Phan\Language\Element\Parameter::create /home/tyson/programming/phan/src/Phan/Language/Element/Parameter.php:63
1 Phan\Language\Element\FunctionFactory::Phan\Language\Element\{closure} /home/tyson/programming/phan/src/Phan/Language/Element/FunctionFactory.php:186
2 array_map <internal>:-1
3 Phan\Language\Element\FunctionFactory::functionListFromFunction /home/tyson/programming/phan/src/Phan/Language/Element/FunctionFactory.php:168
4 Phan\Language\Element\FunctionFactory::functionListFromSignature /home/tyson/programming/phan/src/Phan/Language/Element/FunctionFactory.php:74
5 Phan\CodeBase::hasInternalFunctionWithFQSEN /home/tyson/programming/phan/src/Phan/CodeBase.php:1392
6 Phan\CodeBase::hasFunctionWithFQSEN /home/tyson/programming/phan/src/Phan/CodeBase.php:1158
7 Phan\Analysis::loadMethodPlugins /home/tyson/programming/phan/src/Phan/Analysis.php:341
8 Phan\Phan::finishAnalyzingRemainingStatements /home/tyson/programming/phan/src/Phan/Phan.php:318
9 Phan\Phan::analyzeFileList /home/tyson/programming/phan/src/Phan/Phan.php:122
10 Phan\Tests\AbstractPhanFileTest::testFiles /home/tyson/programming/phan/tests/Phan/AbstractPhanFileTest.php:146
11 PHPUnit\Framework\TestCase::runTest /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestCase.php:1141
12 PHPUnit\Framework\TestCase::runBare /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestCase.php:811
13 PHPUnit\Framework\TestResult::run /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestResult.php:605
14 PHPUnit\Framework\TestCase::run /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestCase.php:667
15 PHPUnit\Framework\TestSuite::run /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678
16 PHPUnit\Framework\TestSuite::run /home/tyson/programming/phan/vendor/phpunit/phpunit/src/Framework/TestSuite.php:678
17 PHPUnit\TextUI\TestRunner::doRun /home/tyson/programming/phan/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:155
18 PHPUnit\TextUI\Command::run /home/tyson/programming/phan/vendor/phpunit/phpunit/src/TextUI/Command.php:171
19 PHPUnit\TextUI\Command::main /home/tyson/programming/phan/vendor/phpunit/phpunit/src/TextUI/Command.php:158
20 <main> /home/tyson/programming/phan/vendor/phpunit/phpunit/phpunit:1


PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

.................F.............................................  63 / 105 ( 60%)
.....F...................
Program received signal SIGSEGV, Segmentation fault.
0x0000000000900a8f in zend_gc_collect_cycles ()
(gdb) bt
#0  0x0000000000900a8f in zend_gc_collect_cycles ()
#1  0x00000000008ff499 in gc_possible_root_when_full ()
#2  0x000000000096c17a in execute_ex ()
#3  0x00000000008c2acc in zend_call_function ()
#4  0x0000000000796626 in zif_array_map ()
#5  0x0000000000966093 in execute_ex ()
#6  0x00000000009702dc in zend_execute ()
#7  0x00000000008d4733 in zend_execute_scripts ()
#8  0x000000000085e378 in php_execute_script ()
#9  0x0000000000972783 in do_cli ()
#10 0x0000000000464ac3 in main ()
 [2019-11-15 14:42 UTC] nikic@php.net
I can't reproduce this on a debug+nts build with opcache without jit. No warnings under valgrind either.
 [2019-11-15 14:44 UTC] tandre@php.net
The valgrind errors I saw with php ZTS debug after the str_pad fix are below - I see the memory that was pointed to was realloced?

gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609


~/programming/phan ±1a0d7a677⚡ » php --version
PHP 8.0.0-dev (cli) (built: Nov 15 2019 08:35:24) ( ZTS DEBUG )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.0-dev, Copyright (c), by Zend Technologies
~/programming/phan ±1a0d7a677⚡ » valgrind `which php` vendor/bin/phpunit tests/Phan/PhanTest5.php
==23609== Memcheck, a memory error detector
==23609== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==23609== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==23609== Command: /path/to/php-8.0.0-debug-opcache-zts-install/bin/php vendor/bin/phpunit tests/Phan/PhanTest5.php
==23609==
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

WARNING: Phan is around twice as slow when php is compiled with --enable-debug (That option is only needed when debugging Phan itself).
(The above warning(s) about slow PHP settings can be disabled by setting 'skip_slow_php_options_warning' to true in .phan/config.php)
.................F.............................................  63 / 105 ( 60%)
.....F...................==23609== Invalid write of size 8
==23609==    at 0xB24BFA: zend_gc_collect_cycles (zend_gc.c:1562)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==  Address 0x1a8be750 is 16 bytes inside a block of size 262,144 free'd
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB224AA: gc_possible_root_when_full (zend_gc.c:606)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xAE6811: gc_check_possible_root (zend_gc.h:83)
==23609==    by 0xAE6863: i_zval_ptr_dtor (zend_variables.h:46)
==23609==    by 0xAE6A38: zval_ptr_dtor (zend_variables.c:84)
==23609==    by 0x867BCA: spl_object_storage_dtor (spl_observer.c:151)
==23609==    by 0xB029B7: zend_hash_destroy (zend_hash.c:1544)
==23609==    by 0x867A18: spl_SplObjectStorage_free_storage (spl_observer.c:108)
==23609==    by 0xB428BA: zend_objects_store_del (zend_objects_API.c:193)
==23609==  Block was alloc'd at
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB2228B: gc_adjust_threshold (zend_gc.c:567)
==23609==    by 0xB223F2: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==    by 0xBC6CD3: do_cli (php_cli.c:959)
==23609==
==23609== Invalid read of size 8
==23609==    at 0xB24A48: zend_gc_collect_cycles (zend_gc.c:1545)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==  Address 0x1a8be758 is 24 bytes inside a block of size 262,144 free'd
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB224AA: gc_possible_root_when_full (zend_gc.c:606)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xAE6811: gc_check_possible_root (zend_gc.h:83)
==23609==    by 0xAE6863: i_zval_ptr_dtor (zend_variables.h:46)
==23609==    by 0xAE6A38: zval_ptr_dtor (zend_variables.c:84)
==23609==    by 0x867BCA: spl_object_storage_dtor (spl_observer.c:151)
==23609==    by 0xB029B7: zend_hash_destroy (zend_hash.c:1544)
==23609==    by 0x867A18: spl_SplObjectStorage_free_storage (spl_observer.c:108)
==23609==    by 0xB428BA: zend_objects_store_del (zend_objects_API.c:193)
==23609==  Block was alloc'd at
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB2228B: gc_adjust_threshold (zend_gc.c:567)
==23609==    by 0xB223F2: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==    by 0xBC6CD3: do_cli (php_cli.c:959)
==23609==
==23609== Invalid read of size 8
==23609==    at 0xB24A5F: zend_gc_collect_cycles (zend_gc.c:1546)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==  Address 0x1a8be758 is 24 bytes inside a block of size 262,144 free'd
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB224AA: gc_possible_root_when_full (zend_gc.c:606)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xAE6811: gc_check_possible_root (zend_gc.h:83)
==23609==    by 0xAE6863: i_zval_ptr_dtor (zend_variables.h:46)
==23609==    by 0xAE6A38: zval_ptr_dtor (zend_variables.c:84)
==23609==    by 0x867BCA: spl_object_storage_dtor (spl_observer.c:151)
==23609==    by 0xB029B7: zend_hash_destroy (zend_hash.c:1544)
==23609==    by 0x867A18: spl_SplObjectStorage_free_storage (spl_observer.c:108)
==23609==    by 0xB428BA: zend_objects_store_del (zend_objects_API.c:193)
==23609==  Block was alloc'd at
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB2228B: gc_adjust_threshold (zend_gc.c:567)
==23609==    by 0xB223F2: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==    by 0xBC6CD3: do_cli (php_cli.c:959)
==23609==
==23609== Conditional jump or move depends on uninitialised value(s)
==23609==    at 0xB24CB6: zend_gc_collect_cycles (zend_gc.c:1581)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==
==23609== Invalid read of size 8
==23609==    at 0xB24CAC: zend_gc_collect_cycles (zend_gc.c:1581)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==    by 0xAEBE76: zend_execute_scripts (zend.c:1666)
==23609==    by 0xA44A2B: php_execute_script (main.c:2586)
==23609==  Address 0x1d505a60 is 0 bytes after a block of size 524,288 alloc'd
==23609==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==23609==    by 0xAB1298: __zend_realloc (zend_alloc.c:2994)
==23609==    by 0xB221E3: gc_grow_root_buffer (zend_gc.c:548)
==23609==    by 0xB224AA: gc_possible_root_when_full (zend_gc.c:606)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xAE6811: gc_check_possible_root (zend_gc.h:83)
==23609==    by 0xAE6863: i_zval_ptr_dtor (zend_variables.h:46)
==23609==    by 0xAE6A38: zval_ptr_dtor (zend_variables.c:84)
==23609==    by 0x867BCA: spl_object_storage_dtor (spl_observer.c:151)
==23609==    by 0xB029B7: zend_hash_destroy (zend_hash.c:1544)
==23609==    by 0x867A18: spl_SplObjectStorage_free_storage (spl_observer.c:108)
==23609==    by 0xB428BA: zend_objects_store_del (zend_objects_API.c:193)
==23609==
==23609== Invalid read of size 4
==23609==    at 0xAAD619: zend_mm_free_heap (zend_alloc.c:1366)
==23609==    by 0xAB01DD: _efree (zend_alloc.c:2549)
==23609==    by 0xB24D1B: zend_gc_collect_cycles (zend_gc.c:1585)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==  Address 0x1ff00000208 is not stack'd, malloc'd or (recently) free'd
==23609==
==23609==
==23609== Process terminating with default action of signal 11 (SIGSEGV)
==23609==  Access not within mapped region at address 0x1FF00000208
==23609==    at 0xAAD619: zend_mm_free_heap (zend_alloc.c:1366)
==23609==    by 0xAB01DD: _efree (zend_alloc.c:2549)
==23609==    by 0xB24D1B: zend_gc_collect_cycles (zend_gc.c:1585)
==23609==    by 0xB223EB: gc_possible_root_when_full (zend_gc.c:592)
==23609==    by 0xB22621: gc_possible_root (zend_gc.c:642)
==23609==    by 0xB4E55D: zend_object_release (zend_objects_API.h:77)
==23609==    by 0xBBFE31: execute_ex (zend_vm_execute.h:51386)
==23609==    by 0xAD4409: zend_call_function (zend_execute_API.c:779)
==23609==    by 0x8A4B79: zif_array_map (array.c:6221)
==23609==    by 0xB5D5FE: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1278)
==23609==    by 0xBC02F1: execute_ex (zend_vm_execute.h:51498)
==23609==    by 0xBC4393: zend_execute (zend_vm_execute.h:55566)
==23609==  If you believe this happened as a result of a stack
==23609==  overflow in your program's main thread (unlikely but
==23609==  possible), you can try to increase the size of the
==23609==  main thread stack using the --main-stacksize= flag.
==23609==  The main thread stack size used in this run was 8388608.
==23609==
==23609== HEAP SUMMARY:
==23609==     in use at exit: 4,754,169 bytes in 33,998 blocks
==23609==   total heap usage: 45,058 allocs, 11,060 frees, 12,676,399 bytes allocated
==23609==
==23609== LEAK SUMMARY:
==23609==    definitely lost: 7,200 bytes in 300 blocks
==23609==    indirectly lost: 0 bytes in 0 blocks
==23609==      possibly lost: 3,270,104 bytes in 26,573 blocks
==23609==    still reachable: 1,476,865 bytes in 7,125 blocks
==23609==         suppressed: 0 bytes in 0 blocks
==23609== Rerun with --leak-check=full to see details of leaked memory
==23609==
==23609== For counts of detected and suppressed errors, rerun with: -v
==23609== Use --track-origins=yes to see where uninitialised values come from
==23609== ERROR SUMMARY: 217915 errors from 6 contexts (suppressed: 0 from 0)
[1]    23609 segmentation fault  valgrind `which php` vendor/bin/phpunit tests/Phan/PhanTest5.php
 [2019-11-20 00:06 UTC] tandre@php.net
I tried again with a build from November 19th. for php-src commit f7c44ef2a0e1e1e5bed5527b8899c66b00416f43

(gdb) run
Starting program: /path/to/php-8.0.0-dev-debug-install/bin/php vendor/bin/phpunit tests/Phan/PhanTest5.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

WARNING: Phan is around twice as slow when php is compiled with --enable-debug (That option is only needed when debugging Phan itself).
(The above warning(s) about slow PHP settings can be disabled by setting 'skip_slow_php_options_warning' to true in .phan/config.php)
.................F.............................................  63 / 105 ( 60%)
.....F...................
Program received signal SIGSEGV, Segmentation fault.
0x0000000000b24c1b in zend_gc_collect_cycles () at /path/to/php-src/Zend/zend_gc.c:1562
1562                                            current->ref = GC_MAKE_GARBAGE(((char*)obj) - obj->handlers->offset);
(gdb) bt
#0  0x0000000000b24c1b in zend_gc_collect_cycles () at /path/to/php-src/Zend/zend_gc.c:1562
#1  0x0000000000b22436 in gc_possible_root_when_full (ref=0x7fffe8358cc0) at /path/to/php-src/Zend/zend_gc.c:592
#2  0x0000000000b2266c in gc_possible_root (ref=0x7fffe8358cc0) at /path/to/php-src/Zend/zend_gc.c:642
#3  0x0000000000b4dae1 in gc_check_possible_root (ref=0x7fffe8358cc0) at /path/to/php-src/Zend/zend_gc.h:83
#4  0x0000000000b5875e in i_free_compiled_variables (execute_data=0x7fffeb616620) at /path/to/php-src/Zend/zend_execute.c:3377
#5  0x0000000000bc023f in execute_ex (ex=0x7fffeb616620) at /path/to/php-src/Zend/zend_vm_execute.h:51476
#6  0x0000000000ad4454 in zend_call_function (fci=0x7fffffff9dc0, fci_cache=0x7fffffff9da0) at /path/to/php-src/Zend/zend_execute_API.c:779
#7  0x00000000008a4bc4 in zif_array_map (execute_data=0x7fffeb6165b0, return_value=0x7fffeb6165a0) at /path/to/php-src/ext/standard/array.c:6221
#8  0x0000000000b5d647 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /path/to/php-src/Zend/zend_vm_execute.h:1278
#9  0x0000000000bc03bb in execute_ex (ex=0x7fffeb615020) at /path/to/php-src/Zend/zend_vm_execute.h:51521
#10 0x0000000000bc445d in zend_execute (op_array=0x7fffeb672300, return_value=0x0) at /path/to/php-src/Zend/zend_vm_execute.h:55589
#11 0x0000000000aebec1 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /path/to/php-src/Zend/zend.c:1666
#12 0x0000000000a44a76 in php_execute_script (primary_file=0x7fffffffc5c0) at /path/to/php-src/main/main.c:2586
#13 0x0000000000bc6ed8 in do_cli (argc=3, argv=0x1867780) at /path/to/php-src/sapi/cli/php_cli.c:959
#14 0x0000000000bc8038 in main (argc=3, argv=0x1867780) at /path/to/php-src/sapi/cli/php_cli.c:1350


I note that obj is used immediately after free_obj is invoked.
I think that this could cause problems if the root buffer is moved due to whatever the implementation of free_obj is (e.g. if it calls destructors on instance properties of the object, for SplObjectStorage or any other )

					if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
						GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
						GC_ADDREF(obj);
						obj->handlers->free_obj(obj);
						GC_DELREF(obj);  // this would be an invalid pointer if the root buffer was moved, e.g. due to spl_SplObjectStorage_free_storage freeing memory of other properties
					}

The implementation of free_obj for SplObjectStorage is:

void spl_SplObjectStorage_free_storage(zend_object *object) /* {{{ */
{
	spl_SplObjectStorage *intern = spl_object_storage_from_obj(object);

	zend_object_std_dtor(&intern->std);

	zend_hash_destroy(&intern->storage);

	if (intern->gcdata != NULL) {
		efree(intern->gcdata);
	}

} /* }}} */
 [2019-11-20 00:19 UTC] tandre@php.net
https://github.com/php/php-src/pull/4935 fixes this locally. (Tested with ZTS DEBUG - the segfault happened before that PR and was fixed by that PR)
 [2019-11-23 15:49 UTC] tandre@php.net
-Status: Feedback +Status: Closed -Assigned To: +Assigned To: tandre
 [2019-11-23 15:49 UTC] tandre@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 19:01:28 2024 UTC