Bug #78811 [Com]: Crash seen during cyclic garbage collection in Phan's unit tests
| From: | tandre@php.net | Date: | Wed, 20 Nov 2019 00:19:35 +0000 |
| Subject: | Bug #78811 [Com]: Crash seen during cyclic garbage collection in Phan's unit tests | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-223802@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78811&edit=1
ID: 78811
Comment by: tandre@php.net
Reported by: tandre@php.net
Summary: Crash seen during cyclic garbage collection in
Phan's unit tests
Status: Feedback
Type: Bug
Package: Reproducible crash
Operating System: Linux Mint 18.3 Sylvia
PHP Version: Next Major Version
Block user comment: N
Private report: N
New Comment:
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)
Previous Comments:
------------------------------------------------------------------------
[2019-11-20 00:06:14] 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-15 14:55:48] nikic@php.net
Please give this another try with https://github.com/php/php-src/commit/3f4a15113c50d2e86a59db8d41fb0a102f43d1c2.
------------------------------------------------------------------------
[2019-11-15 14:44:48] 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
------------------------------------------------------------------------
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=78811
--
Edit this bug report at https://bugs.php.net/bug.php?id=78811&edit=1