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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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

Pull Requests

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-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 02:01:35 2025 UTC