Bug #64827 [Asn->Fbk]: Segfault in zval_mark_grey (zend_gc.c)
| From: | cmb@php.net | Date: | Tue, 03 Nov 2020 18:06:32 +0000 |
| Subject: | Bug #64827 [Asn->Fbk]: Segfault in zval_mark_grey (zend_gc.c) | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-230093@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=64827&edit=1
ID: 64827
Updated by: cmb@php.net
Reported by: odoucet@php.net
Summary: Segfault in zval_mark_grey (zend_gc.c)
-Status: Assigned
+Status: Feedback
Type: Bug
Package: opcache
Operating System: Linux
PHP Version: 5.4.15
-Assigned To: laruence
+Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
Does this still happen with any of the actively supported PHP
versions[1]?
[1] <https://www.php.net/supported-versions.php>
Previous Comments:
------------------------------------------------------------------------
[2016-06-18 05:31:40] 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;
}
}
------------------------------------------------------------------------
[2015-04-21 16:01:42] 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.
------------------------------------------------------------------------
[2015-04-21 15:56:25] 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
------------------------------------------------------------------------
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=64827
--
Edit this bug report at https://bugs.php.net/bug.php?id=64827&edit=1