php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #64827 Segfault in zval_mark_grey (zend_gc.c)
Submitted: 2013-05-13 15:17 UTC Modified: 2020-11-15 04:22 UTC
Votes:7
Avg. Score:4.3 ± 0.9
Reproduced:7 of 7 (100.0%)
Same Version:2 (28.6%)
Same OS:5 (71.4%)
From: odoucet@php.net Assigned: cmb (profile)
Status: No Feedback Package: opcache
PHP Version: 5.4.15 OS: Linux
Private report: No CVE-ID: None
 [2013-05-13 15:17 UTC] odoucet@php.net
Description:
------------
Bug cannot be reproduced easily, as it requires a Magento install with many 
products in it.
Bug can be reproduced on PHP 5.4.15 and 5.3.25
It does not happen when using cgi mode (only on FastCGI). I assume memory 
management is not handled equally between these 
modes.

Running a specific page on Magento, page is rendered correctly, but at the end a 
SIGSEGV happens on PHP process.

Program received signal SIGSEGV, Segmentation fault.
zval_mark_grey (pz=0x272afb8) at /usr/src/build/php-5.4.15/Zend/zend_gc.c:388

(if needed, you can check source code here : http://svn.php.net/viewvc/php/php-
src/trunk/Zend/zend_gc.c?view=markup)

Tell me how I can help debug this error, as I cannot provide a reproducible 
code.

Expected result:
----------------
result page complete with no error

Actual result:
--------------
result page complete + SIGSEGV of the process after, which leads to streange 
behaviour depending on server used (nginx hides 
the segfault, Apache concatenates a 500 error page if used with mod_fcgid).

(gdb) bt
#0  zval_mark_grey (pz=0x272afb8) at /usr/src/build/php-
5.4.15/Zend/zend_gc.c:388
#1  0x00000000007fafe5 in zval_mark_grey (pz=0x272afb8) at /usr/src/build/php-
5.4.15/Zend/zend_gc.c:432
#2  0x00000000007fbf05 in gc_mark_roots () at /usr/src/build/php-
5.4.15/Zend/zend_gc.c:501
#3  gc_collect_cycles () at /usr/src/build/php-5.4.15/Zend/zend_gc.c:795
#4  0x00000000007fc290 in gc_zval_possible_root (zv=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_gc.c:166
#5  0x00000000007fe297 in zend_object_std_dtor (object=0x390ab38) at 
/usr/src/build/php-5.4.15/Zend/zend_objects.c:54
#6  0x00000000007fe2c9 in zend_objects_free_object_storage (object=0x272afb8) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects.c:137
#7  0x000000000080406b in zend_objects_store_del_ref_by_handle_ex (handle=
<optimized out>, handlers=<optimized out>)
    at /usr/src/build/php-5.4.15/Zend/zend_objects_API.c:221
#8  0x0000000000804093 in zend_objects_store_del_ref (zobject=0x390b088) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects_API.c:173
#9  0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#10 _zval_ptr_dtor (zval_ptr=0x39781f8) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#11 0x00000000007e9200 in zend_hash_destroy (ht=0x3978130) at 
/usr/src/build/php-5.4.15/Zend/zend_hash.c:560
#12 0x00000000007db01d in _zval_dtor_func (zvalue=0x390acd0) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.c:45
#13 0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#14 _zval_ptr_dtor (zval_ptr=0x390d798) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#15 0x00000000007fe297 in zend_object_std_dtor (object=0x38e4fb8) at 
/usr/src/build/php-5.4.15/Zend/zend_objects.c:54
#16 0x00000000007fe2c9 in zend_objects_free_object_storage (object=0x272afb8) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects.c:137
#17 0x000000000080406b in zend_objects_store_del_ref_by_handle_ex (handle=
<optimized out>, handlers=<optimized out>)
    at /usr/src/build/php-5.4.15/Zend/zend_objects_API.c:221
#18 0x0000000000804093 in zend_objects_store_del_ref (zobject=0x3992400) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects_API.c:173
#19 0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#20 _zval_ptr_dtor (zval_ptr=0x39922f8) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#21 0x00000000007e9200 in zend_hash_destroy (ht=0x2533ab8) at 
/usr/src/build/php-5.4.15/Zend/zend_hash.c:560
#22 0x00000000007db01d in _zval_dtor_func (zvalue=0x2528948) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.c:45
#23 0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#24 _zval_ptr_dtor (zval_ptr=0x2518c40) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#25 0x00000000007fe297 in zend_object_std_dtor (object=0x250cd28) at 
/usr/src/build/php-5.4.15/Zend/zend_objects.c:54
#26 0x00000000007fe2c9 in zend_objects_free_object_storage (object=0x272afb8) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects.c:137
#27 0x000000000080406b in zend_objects_store_del_ref_by_handle_ex (handle=
<optimized out>, handlers=<optimized out>)
    at /usr/src/build/php-5.4.15/Zend/zend_objects_API.c:221
#28 0x0000000000804093 in zend_objects_store_del_ref (zobject=0x250cb78) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects_API.c:173
#29 0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#30 _zval_ptr_dtor (zval_ptr=0x2533c30) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#31 0x00000000007e9200 in zend_hash_destroy (ht=0x2528898) at 
/usr/src/build/php-5.4.15/Zend/zend_hash.c:560
#32 0x00000000007db01d in _zval_dtor_func (zvalue=0x2523e80) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.c:45
#33 0x00000000007ce03d in _zval_dtor (zvalue=<optimized out>) at 
/usr/src/build/php-5.4.15/Zend/zend_variables.h:35
#34 _zval_ptr_dtor (zval_ptr=0x25336d0) at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:438
#35 0x00000000007fe297 in zend_object_std_dtor (object=0x2537758) at 
/usr/src/build/php-5.4.15/Zend/zend_objects.c:54
#36 0x00000000007fe2c9 in zend_objects_free_object_storage (object=0x272afb8) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects.c:137
#37 0x000000000080406b in zend_objects_store_del_ref_by_handle_ex (handle=
<optimized out>, handlers=<optimized out>)
    at /usr/src/build/php-5.4.15/Zend/zend_objects_API.c:221
#38 0x0000000000804093 in zend_objects_store_del_ref (zobject=0x25376c8) at 
/usr/src/build/php-
5.4.15/Zend/zend_objects_API.c:173
#39 0x00007fc2385281a7 in accel_fast_hash_destroy (ht=<optimized out>) at 
/usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2141
#40 accel_fast_zval_ptr_dtor (zval_ptr=<optimized out>) at 
/usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2162
#41 0x00007fc23852823f in accel_clean_non_persistent_class (pce=<optimized out>) 
at 
/usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2238
#42 0x00000000007e8f73 in zend_hash_reverse_apply (ht=0x2174c60, 
apply_func=0x7fc2385281f0 <accel_clean_non_persistent_class>)
    at /usr/src/build/php-5.4.15/Zend/zend_hash.c:799
#43 0x00007fc238528042 in zend_accel_fast_shutdown () at 
/usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2290
#44 0x00007fc23852bddd in accel_deactivate () at 
/usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2319
#45 0x00000000007d16be in zend_llist_apply (l=<optimized out>, func=0x7cd270 
<zend_extension_deactivator>)
    at /usr/src/build/php-5.4.15/Zend/zend_llist.c:193
#46 0x00000000007d0c7b in shutdown_executor () at /usr/src/build/php-
5.4.15/Zend/zend_execute_API.c:246
#47 0x00000000007dc302 in zend_deactivate () at /usr/src/build/php-
5.4.15/Zend/zend.c:938
#48 0x000000000077dfbc in php_request_shutdown (dummy=<optimized out>) at 
/usr/src/build/php-5.4.15/main/main.c:1800
#49 0x000000000088c10c in main (argc=<optimized out>, argv=<optimized out>) at 
/usr/src/build/php-
5.4.15/sapi/cgi/cgi_main.c:2502


[...]
with breakpoint line 388: 
(gdb) print *pz
$9 = {value = {lval = 743, dval = 3.6709077486004618e-321, str = {val = 0x2e7 
<Address 0x2e7 out of bounds>, len = 16560416}, 
ht = 0x2e7,
    obj = {handle = 743, handlers = 0xfcb120}}, refcount__gc = 0, type = 5 
'\005', is_ref__gc = 0 '\000'}
(gdb) print obj
$10 = <optimized out>


Patches

php-5.6.22-patch-zval_mark_grey.patch (last revision 2016-06-18 05:42 UTC by ta-sdz at deshammer dot net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-05-13 15:33 UTC] johannes@php.net
-Status: Open +Status: Not a bug
 [2013-05-13 15:33 UTC] johannes@php.net
Do not file bugs when you have Zend extensions (zend_extension=)
loaded. Examples are Zend Optimizer, Zend Debugger, Turck MM Cache,
APC, Xdebug and ionCube loader.  These extensions often modify engine
behavior which is not related to PHP itself.

.
 [2013-05-14 02:54 UTC] laruence@php.net
-Status: Not a bug +Status: Re-Opened -Package: *General Issues +Package: optimizer
 [2013-05-14 02:56 UTC] laruence@php.net
-Status: Re-Opened +Status: Open
 [2013-05-14 15:40 UTC] rasmus@php.net
I can confirm I am seeing these too occasionally. As far as I can tell they 
happen very infrequently, but when they happen it is usually on a request that 
was interrupted due to hitting the memory limit. 

Here is a backtrace with full symbols: https://gist.github.com/anonymous/5576932
 [2013-05-19 15:02 UTC] laruence@php.net
-Assigned To: +Assigned To: dmitry
 [2013-05-19 15:02 UTC] laruence@php.net
hmm, dmitry, before I look into this, maybe you have some hints?

thanks :)
 [2013-05-19 22:02 UTC] odoucet@php.net
bug still applies on PHP 5.5.0rc1
Backtrace with this version : https://gist.github.com/odoucet/5609218
 [2013-06-05 11:32 UTC] arjen at react dot com
https://bugs.php.net/bug.php?id=64868 also crashes in zval_mark_grey
 [2013-06-14 18:48 UTC] ircmaxell@php.net
Can you attempt to reproduce this using PHP from this branch: 
https://github.com/ircmaxell/php-src/tree/zval_mark_grey_tail_recursion ? I was 
working on fixing another issue, and would like to see if it solves this as 
well... I don't expect it to, but if it does that would be more justification for 
this refactor.

Thanks!
 [2013-06-17 12:01 UTC] odoucet@php.net
I tried reproducing this bug with your branch 'zval_mark_grey_tail_recursion' (commit bc785a8eea). 
It still produces a segfault, but not at the same place.

With PHP 5.5.0rc1, segfault happens _after_ the page is loaded.
With your version, it happens before any page output : 

Program received signal SIGSEGV, Segmentation fault.
zend_objects_store_del_ref_by_handle_ex (handle=47, handlers=0x101b440)
    at /usr/src/build/php/php-src-zval_mark_grey_tail_recursion/Zend/zend_objects_API.c:183

Backtrace seems recursive, so I posted a snippet here : 
https://gist.github.com/odoucet/5796378
 [2013-06-17 15:09 UTC] ircmaxell@php.net
odoucet,

Can you follow up in the comment thread for the gist (let's keep that thread 
there, as it'll keep noise out of here): 
https://gist.github.com/odoucet/5796378/#comment-846571 ? Thanks!
 [2013-06-18 11:39 UTC] ircmaxell@php.net
So digging through the original backtrace that you posted on the issue, I see what's going on.

Basically, the garbage collector is being fired during the destruction of an object. This causes 
zval_mark_grey() to run on the partially destroyed object (specifically the hash table) and hence the segfault 
when it tries to access previously free()'d memory.

I am still working out the exact circumstances this takes to be triggered (to work on a fix), but what it 
seems like is that the object's zval still exists during destruction here: 
http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_objects_API.c#172 which then could still be found by reference by 
the garbage collector.

Off the top of my head, there appear to be two basic ways of fixing this. The first would be to put a lock on 
the garbage collector to prevent it from being run during any dtor call (zval_dtor, zval_ptr_dtor, 
zend_object_std_dtor, etc). This may be the simple "hack" to prevent the segfault.

The second possible solution here (and likely better) would be to edit zend_objects_store_del_ref_by_handle_ex 
to also accept the object's zval. This would allow it to properly set the zval's type to IS_NULL on 
destruction here: http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_objects_API.c#217 just like is currently done 
for arrays here: http://lxr.php.net/xref/PHP_5_3/Zend/zend_variables.c#44

However that's an API change, which may have a larger impact than desired (although the only places in core 
that use it are the object API and the GC).

I'm going to experiment some more today and will post back more findings...
 [2013-06-20 10:19 UTC] laruence@php.net
-Assigned To: dmitry +Assigned To: laruence
 [2013-06-20 10:19 UTC] laruence@php.net
@odoucet is that possible that you could give me a access to you box which can 
reproduce this segfault?

thanks
 [2013-06-20 14:18 UTC] odoucet@php.net
Sorry, application is too difficult to package and there is some private data in 
it. ATM, we should go on with our previous tests : you provide branches and I test 
it :(
 [2013-06-20 14:35 UTC] arjen at react dot com
Any chance fixing #64896 or two of the three issues in #63481 helps resolving 
this problem?

Those bugs DO have simple scripts to reproduce them and also show 
zend_hash_destroy/zend_objects_free_object_storage combined with 
zval_dtor/zval_ptr_dtor/zend_object_std_dtor in the backtraces...

#64896 even contains gc_collect_cycles in the bt, however it does not crash 
during shutdown..
 [2013-06-25 05:49 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=157ccaf507b7a94c43db4ec1b7321aac5cc68e8b
Log: Fixed bug #64827 Segfault in zval_mark_grey (zend_gc.c)
 [2013-06-25 05:49 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 [2013-11-17 09:30 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=157ccaf507b7a94c43db4ec1b7321aac5cc68e8b
Log: Fixed bug #64827 Segfault in zval_mark_grey (zend_gc.c)
 [2014-02-10 15:47 UTC] odoucet@php.net
-Status: Closed +Status: Assigned
 [2014-02-10 15:47 UTC] odoucet@php.net
I still experience this bug with latest version PHP 5.4.25 : 
https://gist.github.com/odoucet/8918221
 [2014-11-25 21:27 UTC] salsi at icosaedro dot it
Got the same exact issue here with php-5.7.0-dev downloaded right now from the repository, with SIGSEGV in zend_gc.c:319:

if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {

The bug is easily reproducible by executing my PHPLint program (available from the CVS, no external libs or special extensions required) and issuing the command that generates the documents from the sources:

./php utils/GenerateDoc.php --move stdlib doc/stdlib stdlib

The GenerateDoc.php program crashes with the error above after about 3.5 minutes of processing. For the record, php-5.6.3 works perfectly, although being about 30% slower.
 [2015-01-12 15:51 UTC] odoucet@php.net
Same error with FPM (PHP version 5.4.32)

#0  zval_mark_grey (pz=0x14c8e80) at /usr/src/build/php/php-5.4.32/Zend/zend_gc.c:388
#1  0x0000000000800f15 in zval_mark_grey (pz=0x14c8e80) at /usr/src/build/php/php-5.4.32/Zend/zend_gc.c:432
#2  0x0000000000801e35 in gc_mark_roots () at /usr/src/build/php/php-5.4.32/Zend/zend_gc.c:501
#3  gc_collect_cycles () at /usr/src/build/php/php-5.4.32/Zend/zend_gc.c:795
#4  0x00000000008021c0 in gc_zval_possible_root (zv=<optimized out>) at /usr/src/build/php/php-5.4.32/Zend/zend_gc.c:166
#5  0x00000000008041c7 in zend_object_std_dtor (object=0x1d28870) at /usr/src/build/php/php-5.4.32/Zend/zend_objects.c:54
#6  0x00000000008041f9 in zend_objects_free_object_storage (object=0x14c8e80) at /usr/src/build/php/php-5.4.32/Zend/zend_objects.c:137
#7  0x0000000000809fcb in zend_objects_store_del_ref_by_handle_ex (handle=<optimized out>, handlers=<optimized out>)
    at /usr/src/build/php/php-5.4.32/Zend/zend_objects_API.c:226
#8  0x0000000000809ff3 in zend_objects_store_del_ref (zobject=0x1d28990) at /usr/src/build/php/php-5.4.32/Zend/zend_objects_API.c:178
#9  0x00007f0b83ce91a7 in accel_fast_hash_destroy (ht=<optimized out>) at /usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2141
#10 accel_fast_zval_ptr_dtor (zval_ptr=<optimized out>) at /usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2162
#11 0x00007f0b83ce923f in accel_clean_non_persistent_class (pce=<optimized out>) at /usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2238
#12 0x00000000007eeb03 in zend_hash_reverse_apply (ht=0x1134c60, apply_func=0x7f0b83ce91f0 <accel_clean_non_persistent_class>)
    at /usr/src/build/php/php-5.4.32/Zend/zend_hash.c:799
#13 0x00007f0b83ce9042 in zend_accel_fast_shutdown () at /usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2290
#14 0x00007f0b83cecddd in accel_deactivate () at /usr/src/build/ZendOptimizerPlus/ZendAccelerator.c:2319
#15 0x00000000007d70ee in zend_llist_apply (l=<optimized out>, func=0x7d2cc0 <zend_extension_deactivator>)
    at /usr/src/build/php/php-5.4.32/Zend/zend_llist.c:193
#16 0x00000000007d66eb in shutdown_executor () at /usr/src/build/php/php-5.4.32/Zend/zend_execute_API.c:246
#17 0x00000000007e1e02 in zend_deactivate () at /usr/src/build/php/php-5.4.32/Zend/zend.c:934
#18 0x000000000078389c in php_request_shutdown (dummy=<optimized out>) at /usr/src/build/php/php-5.4.32/main/main.c:1808
#19 0x000000000089a259 in main (argc=13073222, argv=<optimized out>) at /usr/src/build/php/php-5.4.32/sapi/fpm/fpm/fpm_main.c:1961


Code extract zend_gc.c:388
373 static void zval_mark_grey(zval *pz TSRMLS_DC)
[...]
383         if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
384             zend_object_get_gc_t get_gc;
385             struct _store_object *obj = &EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj;
386
387             obj->refcount--;
388             if (GC_GET_COLOR(obj->buffered) != GC_GREY) {
389                 GC_BENCH_INC(zobj_marked_grey);
390                 GC_SET_COLOR(obj->buffered, GC_GREY);
 [2015-04-21 15:56 UTC] justin at eblah dot com
I'm also seeing this, but can't reproduce it easily. I can add an additional echo somewhere in the script, and the problem goes away, so I don't know how to reproduce it code wise.

#0  zval_mark_grey (pz=0x7f2b76f7d268) at /usr/src/debug/php-5.6.8/Zend/zend_gc.c:421
#1  0x00000000005e008d in gc_mark_roots () at /usr/src/debug/php-5.6.8/Zend/zend_gc.c:501
#2  gc_collect_cycles () at /usr/src/debug/php-5.6.8/Zend/zend_gc.c:795
#3  0x00000000005e0192 in gc_zobj_possible_root (zv=<value optimized out>) at /usr/src/debug/php-5.6.8/Zend/zend_gc.c:221
#4  0x000000000063f828 in gc_zval_check_possible_root (execute_data=0x7f2b95bb87a0)
    at /usr/src/debug/php-5.6.8/Zend/zend_gc.h:183
#5  zend_assign_to_variable (execute_data=0x7f2b95bb87a0) at /usr/src/debug/php-5.6.8/Zend/zend_execute.c:930
#6  ZEND_ASSIGN_SPEC_CV_VAR_HANDLER (execute_data=0x7f2b95bb87a0) at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:37448
#7  0x000000000062dbe8 in execute_ex (execute_data=0x7f2b95bb87a0) at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:363
#8  0x00000000005af8ce in dtrace_execute_ex (execute_data=0x7f2b95bb87a0) at /usr/src/debug/php-5.6.8/Zend/zend_dtrace.c:73
#9  0x00007f2b7f5cdd4d in nr_php_execute_enabled ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1099
#10 0x00007f2b7f5ce362 in nr_php_execute ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1210
#11 0x000000000063e6bc in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>)
    at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:592
#12 0x000000000062dbe8 in execute_ex (execute_data=0x7f2b95bb8638) at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:363
#13 0x00000000005af8ce in dtrace_execute_ex (execute_data=0x7f2b95bb8638) at /usr/src/debug/php-5.6.8/Zend/zend_dtrace.c:73
#14 0x00007f2b7f5cdd4d in nr_php_execute_enabled ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1099
#15 0x00007f2b7f5ce362 in nr_php_execute ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1210
#16 0x000000000063e6bc in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>)
    at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:592
#17 0x000000000062dbe8 in execute_ex (execute_data=0x7f2b95bb8448) at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:363
#18 0x00000000005af8ce in dtrace_execute_ex (execute_data=0x7f2b95bb8448) at /usr/src/debug/php-5.6.8/Zend/zend_dtrace.c:73
#19 0x00007f2b7f5cdf75 in nr_php_execute_enabled ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:947
#20 0x00007f2b7f5ce362 in nr_php_execute ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1210
#21 0x000000000062d581 in ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER (execute_data=0x7f2b95bb8150)
    at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:8390
#22 0x000000000062dbe8 in execute_ex (execute_data=0x7f2b95bb8150) at /usr/src/debug/php-5.6.8/Zend/zend_vm_execute.h:363
#23 0x00000000005af8ce in dtrace_execute_ex (execute_data=0x7f2b95bb8150) at /usr/src/debug/php-5.6.8/Zend/zend_dtrace.c:73
#24 0x00007f2b7f5cdf75 in nr_php_execute_enabled ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:947
#25 0x00007f2b7f5ce362 in nr_php_execute ()
    at /home/hudson/slave-workspace/workspace/PHP_Release_Agent/label/centos5-64-nrcamp/agent/php_execute.c:1210
#26 0x00000000005bef5c in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/src/debug/php-5.6.8/Zend/zend.c:1341
#27 0x000000000055d77a in php_execute_script (primary_file=0x7fff6856ab30) at /usr/src/debug/php-5.6.8/main/main.c:2597
#28 0x0000000000665ae3 in do_cli (argc=4, argv=0x265c9d0) at /usr/src/debug/php-5.6.8/sapi/cli/php_cli.c:994
#29 0x00000000006662e8 in main (argc=4, argv=0x265c9d0) at /usr/src/debug/php-5.6.8/sapi/cli/php_cli.c:1378
 [2015-04-21 16:01 UTC] justin at eblah dot com
@laruence -- I saw back in 2013 where you requested access to a box where this is happening. I may be able to give you a cloned box to work with if that'd help, but I'd have to talk to some people first. Let me know if interested.
 [2016-06-18 05:31 UTC] ta-sdz at deshammer dot net
Hello everybody on this long outstanding bug.


I think I'm onto something there. 

I had this SIG11 regularly and reproducibly enough to reliably get coredumps in an application too huge to be shared publicly.


Here's one backtrace of them on a 5.6.22 installation:

(gdb) bt full
#0  0x00007f58457a9a6d in zval_mark_grey (pz=<optimized out>) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:420
        p = 0x7f585ca80790
#1  0x00007f58457aab19 in zobj_mark_grey (obj=<optimized out>, pz=<optimized out>) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:454
        i = 0
        n = 4
        table = 0x7f585ca75f00
        p = <optimized out>
        get_gc = <optimized out>
#2  gc_mark_roots () at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:488
        z = {value = {lval = 140015933864297, dval = 6.917706279272916e-310, str = {val = 0x7f5800003969 <Address 0x7f5800003969 out of bounds>, 
              len = 1169556032}, ht = 0x7f5800003969, obj = {handle = 14697, handlers = 0x7f5845b60240 <std_object_handlers>}, 
            ast = 0x7f5800003969}, refcount__gc = 1, type = 88 'X', is_ref__gc = 0 '\000'}
        obj = <optimized out>
        current = 0x7f5844a1be50
#3  gc_collect_cycles () at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:790
        p = <optimized out>
        q = <optimized out>
        orig_free_list = <optimized out>
        orig_next_to_free = <optimized out>
        count = 0
#4  0x00007f58457aae02 in gc_zval_possible_root (zv=0x7f58582723d8) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:163
        newRoot = <optimized out>
#5  0x00007f5845797f48 in zend_hash_destroy (ht=0x7f585ca81008) at /usr/src/debug/php-5.6.22/Zend/zend_hash.c:548
        p = 0x7f585ca7ea00
        q = 0x7f585ca805d8
#6  0x00007f58457b127c in zend_object_std_dtor (object=0x7f585ca7e7b8) at /usr/src/debug/php-5.6.22/Zend/zend_objects.c:44
No locals.
#7  0x00007f58457b1309 in zend_objects_free_object_storage (object=0x7f585ca7e7b8) at /usr/src/debug/php-5.6.22/Zend/zend_objects.c:137
No locals.
#8  0x00007f58457b75ec in zend_objects_store_del_ref_by_handle_ex (handle=14702, handlers=<optimized out>)
    at /usr/src/debug/php-5.6.22/Zend/zend_objects_API.c:226
        __orig_bailout = 0x7ffc1fc46590
        __bailout = {{__jmpbuf = {140017488351064, -2743026434694212569, 140016688292440, 140017400377624, 140016688292440, 0, 
              -2835498401476668377, -2742977752702544857}, __mask_was_saved = 0, __saved_mask = {__val = {140017099424667, 140017103407076, 
                140017086683120, 206158430224, 140720841449808, 140720841449600, 13176172747737717760, 140017103407076, 140017099629640, 
                140720841449824, 140720841449820, 1, 140017086682768, 8, 4, 140017099310240}}}}
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) frame 0
#0  0x00007f58457a9a6d in zval_mark_grey (pz=<optimized out>) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:420
420				pz = *(zval**)p->pData;
(gdb) print p
$1 = (Bucket *) 0x7f585ca80790
(gdb) print *(zval**) p
$2 = (zval *) 0x7f585c102478
(gdb) print *(zval**) p->pData
Cannot access memory at address 0x0
(gdb) print  p->pData
$3 = (void *) 0x0
(gdb)


Now look at that! p->pData is a NULL-Pointer which should reference something. Well - nothing simplier than that - I thought - catch the NULL and be fine.


But ... after catching the (p->pData==NULL) some more came up.

Core was generated by `/usr/sbin/httpd -DFOREGROUND'.
Program terminated with signal 11, Segmentation fault.
#0  zval_mark_grey (pz=0x0) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:422
422					if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
(gdb) print pz
$1 = (zval *) 0x0
(gdb)

So there is (pz==NULL) and this gave the operations on pz in line 422 the creeps.

Well then - let's catch (pz==NULL) as well ... I thought again - or at least I tried.


After catching (p->pData==NULL) and (pz==NULL) the SIG11 wandered into the zval_scan_black() function:

Program terminated with signal 11, Segmentation fault.
#0  0x00007f8e76ac4cbd in zval_scan_black (pz=<optimized out>) at /usr/src/debug/php-5.6.22/Zend/zend_gc.c:313
313			pz = *(zval**)p->pData;
(gdb) print p
$1 = (Bucket *) 0x7f8e8e05e1e0
(gdb) print p->pData
$2 = (void *) 0x0
(gdb) print *p
$3 = {h = 140250165711864, nKeyLength = 2382165776, pData = 0x0, pDataPtr = 0x0, pListNext = 0x0, pListLast = 0x7f8e8e05e3f0, pNext = 0x0, 
  pLast = 0x0, arKey = 0x7f8e5d205fd8 "hackLanguageID"}
(gdb)

and so on and so on - until any loop over p which referenced p->pData or pz was enclosed with a null pointer catch.

After that there were no more SIG11s.

I'm fully aware that this patch should have remedied the cause of the p->pData==NULL and the pz==NULL and not the symptom but this was way over my head. As well as the part of "TODO: Maybe some logging here".


Well - here's the patch which I wanted you to review and maybe add some logging to it:

--- php-5.6.22/Zend/zend_gc.c	2016-05-26 03:08:57.000000000 +0200
+++ php-5.6.22-patched/Zend/zend_gc.c	2016-06-17 21:27:32.226425023 +0200
@@ -310,16 +310,25 @@
 		}
 	}
 	while (p != NULL) {
-		pz = *(zval**)p->pData;
-		if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
-			pz->refcount__gc++;
-		}
-		if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
-			if (p->pListNext == NULL) {
-				goto tail_call;
+		if (p->pData != NULL) {
+			pz = *(zval**)p->pData;
+			if (pz != NULL) {
+				if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+					pz->refcount__gc++;
+				}
+				if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+					if (p->pListNext == NULL) {
+						goto tail_call;
+					} else {
+						zval_scan_black(pz TSRMLS_CC);
+					}
+				}
 			} else {
-				zval_scan_black(pz TSRMLS_CC);
+				/* Now this is really odd ... we've got a p->pData which references a NULL pointer */
 			}
+		} else {
+			/* shall we log something when encountering a p->pData == NULL */
+		
 		}
 		p = p->pListNext;
 	}
@@ -353,12 +362,20 @@
 		}
 		p = props->pListHead;
 		while (p != NULL) {
-			pz = *(zval**)p->pData;
-			if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
-				pz->refcount__gc++;
-			}
-			if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
-				zval_scan_black(pz TSRMLS_CC);
+			if (p->pData != NULL) {
+				pz = *(zval**)p->pData;
+				if (pz != NULL) {
+					if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+						pz->refcount__gc++;
+					}
+					if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
+						zval_scan_black(pz TSRMLS_CC);
+					}
+				} else {
+					/* pz is NULL - maybe there should be some logging? */
+				}
+			} else {
+				/* p->pData is NULL - maybe there should be some logging? */
 			}
 			p = p->pListNext;
 		}
@@ -417,14 +434,23 @@
 			}
 		}
 		while (p != NULL) {
-			pz = *(zval**)p->pData;
-			if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
-				pz->refcount__gc--;
-			}
-			if (p->pListNext == NULL) {
-				goto tail_call;
+			if (p->pData != NULL) {
+				pz = *(zval**)p->pData;
+				if (pz != NULL) {
+					if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+						pz->refcount__gc--;
+					}
+					if (p->pListNext == NULL) {
+						goto tail_call;
+					} else {
+						zval_mark_grey(pz TSRMLS_CC);
+					}
+				} else {
+					/* Now this is odd - we have a valid pz and a pData which is NULL */
+				
+				}
 			} else {
-				zval_mark_grey(pz TSRMLS_CC);
+				/* Some logging maybe? p->pData is NULL */
 			}
 			p = p->pListNext;
 		}
@@ -459,11 +485,19 @@
 			}
 			p = props->pListHead;
 			while (p != NULL) {
-				pz = *(zval**)p->pData;
-				if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
-					pz->refcount__gc--;
+				if (p->pData != NULL) {
+					pz = *(zval**)p->pData;
+					if (pz != NULL) {
+						if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
+							pz->refcount__gc--;
+						}
+						zval_mark_grey(pz TSRMLS_CC);
+					} else {
+						/* TODO: Some logging maybe? */
+					}
+				} else {
+					/* TODO: Some logging maybe? */
 				}
-				zval_mark_grey(pz TSRMLS_CC);
 				p = p->pListNext;
 			}
 		}
 [2017-10-24 23:39 UTC] kalle@php.net
-Package: optimizer +Package: opcache
 [2020-11-03 18:06 UTC] cmb@php.net
-Status: Assigned +Status: Feedback -Assigned To: laruence +Assigned To: cmb
 [2020-11-03 18:06 UTC] cmb@php.net
Does this still happen with any of the actively supported PHP
versions[1]?

[1] <https://www.php.net/supported-versions.php>
 [2020-11-15 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC