Bug #75351 [Com]: Segmentation fault on fatal error during Generator::send
| From: | tandre@php.net | Date: | Mon, 11 Dec 2017 22:18:06 +0000 |
| Subject: | Bug #75351 [Com]: Segmentation fault on fatal error during Generator::send | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-213054@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75351&edit=1
ID: 75351
Comment by: tandre@php.net
Reported by: bashofmann at gmail dot com
Summary: Segmentation fault on fatal error during
Generator::send
Status: Open
Type: Bug
Package: Scripting Engine problem
Operating System: Ubuntu 14.04.5 LTS (GNU/Linux 4.
PHP Version: 7.1.10
Block user comment: N
Private report: N
New Comment:
I'm encountering similar issues, also in Generator->send(). However, the issues I see are in
zend_generator_get_gc instead
It seems like garbage collection is getting triggered when Generator->send() is getting called,
which may be an edge case that isn't handled properly, and may be related to why it's hard
to reproduce.
I'm using
$retval = yield from, $retval = yield some_helper(),
yield other_helper() in the code in question, but the bug happens so infrequently
I'm not sure which part it is. I haven't checked how deeply nested yields are.
I'm using PHP 7.1.9. The source of zend_generators.c is identical for 7.1.9 and 7.1.12
(latest).
Stack trace:
```
... Lines added by newrelic segfault stack trace dumper omitted
/usr/local/php/modules/libphp7.so(+0x431748)[0x7ff795959748]
/usr/local/php/modules/libphp7.so(+0x42d4fa)[0x7ff7959554fa]
/usr/local/php/modules/libphp7.so(zend_gc_collect_cycles+0x78)[0x7ff795956478]
/usr/local/php/modules/libphp7.so(gc_possible_root+0x9e)[0x7ff7959560ee]
/usr/local/php/modules/libphp7.so(+0x43220c)[0x7ff79595a20c]
/usr/local/php/modules/libphp7.so(zend_objects_store_del+0x271)[0x7ff79596c231]
/usr/local/php/modules/libphp7.so(zend_generator_update_current+0x1f0)[0x7ff79595a9b0]
/usr/local/php/modules/libphp7.so(zend_generator_resume+0x1dd)[0x7ff79595a4ad]
/usr/local/php/modules/libphp7.so(+0x433bdf)[0x7ff79595bbdf]
/usr/local/php/modules/libphp7.so(+0x4b70c6)[0x7ff7959df0c6]
/usr/local/php/modules/libphp7.so(execute_ex+0x2b)[0x7ff79597738b]
/usr/local/php/lib/php/20160303/newrelic.so(+0x231bb)[0x7ff78b0b61bb]
/usr/local/php/lib/php/20160303/newrelic.so(+0x23802)[0x7ff78b0b6802]
/usr/local/php/modules/libphp7.so(+0x4b6985)[0x7ff7959de985]
/usr/local/php/modules/libphp7.so(execute_ex+0x2b)[0x7ff79597738b]
/usr/local/php/lib/php/20160303/newrelic.so(+0x231bb)[0x7ff78b0b61bb]
/usr/local/php/lib/php/20160303/newrelic.so(+0x23802)[0x7ff78b0b6802]
```
I added comments to parts of the code that showed up in my stack trace, and
```
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -275,7 +275,7 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */
/* Yield from root references */
if (generator->node.children == 0) {
zend_generator *child = generator, *root = generator->node.ptr.root;
- while (root != child) {
+ while (root != child && child != NULL) { // Not sure if checking
for null would solve the underlying issue for the other bug reported, and I'm not familiar with
how deep the chain goes.
child = child->node.parent;
size++;
}
@@ -340,8 +340,8 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
if (generator->node.children == 0) {
zend_generator *child = generator, *root = generator->node.ptr.root;
- while (root != child) {
- child = child->node.parent;
+ while (root != child && child != NULL) { // Not sure if checking for null
would solve the underlying issue
+ child = child->node.parent; // child->node is somehow equal to null
when the segfault occurs
ZVAL_OBJ(gc_buffer++, &child->std);
}
}
@@ -608,7 +608,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
}
while (!root->execute_data && root != generator) {
- OBJ_RELEASE(&old_root->std);
+ OBJ_RELEASE(&old_root->std); // Not caused by this OBJ_RELEASE. It's
caused by the below one.
old_root = root;
root = zend_generator_get_child(&root->node, leaf);
@@ -638,10 +638,11 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator
*generator
EG(current_execute_data) = original_execute_data;
if (!((old_root ? old_root : generator)->flags
& ZEND_GENERATOR_CURRENTLY_RUNNING)) {
- leaf->node.ptr.root = root;
- root->node.parent = NULL;
+ leaf->node.ptr.root = root; // The root
pointer and root->node pointer were changed.
+ root->node.parent = NULL; // And a
parent gets set to null, which might interfere with zend_generator_get_gc
+ // What happens if there are nested yield froms, though? Would those
still have (something)->node.ptr.root point to old_root?
if (old_root) {
- OBJ_RELEASE(&old_root->std);
+ OBJ_RELEASE(&old_root->std);
// Disassembly shows that this triggers a garbage collection
}
zend_generator_resume(leaf);
return leaf->node.ptr.root; /* this may
be updated during zend_generator_resume! */
```
Previous Comments:
------------------------------------------------------------------------
[2017-10-10 15:15:27] bashofmann at gmail dot com
Description:
------------
We are experiencing segmentation faults related to probably fatal errors when using Generator::send.
Unfortunately I was not able to create a simple script to reproduce this issue.
gdb back trace:
(gdb) bt
#0 calc_gc_buffer_size (generator=0x7f64d68f4a80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:279
#1 zend_generator_get_gc (object=0x7ffe4c963eb0, table=0x7ffe4c963ea8, n=0x7ffe4c963ea4) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:305
#2 0x00005576280aa23a in gc_mark_grey (ref=0x7f64d68f4a80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:499
#3 0x00005576280aa2b6 in gc_mark_grey (ref=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:511
#4 0x00005576280aa2b6 in gc_mark_grey (ref=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:511
#5 0x00005576280aa346 in gc_mark_grey (ref=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:572
#6 0x00005576280aa346 in gc_mark_grey (ref=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:572
#7 0x00005576280ab1e8 in gc_mark_roots () at /build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:598
#8 zend_gc_collect_cycles () at /build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:1072
#9 0x00005576280aae3e in gc_possible_root (ref=0x7ffe4c963eb0, ref@entry=0x7f64d68f5f80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_gc.c:286
#10 0x00005576280af551 in zend_object_release (obj=0x7f64d68f5f80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_objects_API.h:80
#11 zend_generator_update_current (generator=generator@entry=0x7f64d68f4a80, leaf=0x7f64d68f4a80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:667
#12 0x00005576280aefdd in zend_generator_get_current (generator=0x7f64d68f4a80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.h:133
#13 zend_generator_resume (orig_generator=orig_generator@entry=0x7f64d68f4a80) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:845
#14 0x00005576280afe7f in zim_Generator_send (execute_data=0x7f6555a14070,
return_value=0x7ffe4c964210) at /build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:1001
#15 0x000055762811a0cc in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:972
#16 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#17 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#18 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#19 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#20 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#21 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#22 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#23 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#24 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#25 0x0000557628119ae5 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:1076
#26 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#27 0x0000557628119ae5 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:1076
#28 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#29 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#30 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#31 0x00005576280aeede in zend_generator_resume (orig_generator=0x7f64de060780) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_generators.c:815
#32 0x000055762811a0cc in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:972
#33 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#34 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#35 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#36 0x0000557628119ae5 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:1076
#37 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#38 0x00005576280747e1 in zend_call_function (fci=fci@entry=0x7ffe4c964810,
fci_cache=fci_cache@entry=0x7ffe4c9647e0) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_execute_API.c:855
#39 0x0000557627f762ad in reflection_method_invoke (execute_data=<optimized out>,
return_value=0x7f6555a13610, variadic=0) at
/build/php7.1-zUmk8m/php7.1-7.1.9/ext/reflection/php_reflection.c:3342
#40 0x0000557628119c50 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:1099
#41 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#42 0x0000557628119ae5 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:1076
#43 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#44 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#45 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#46 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#47 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#48 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#49 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#50 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#51 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#52 0x0000557628119f65 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:949
#53 0x00005576280c8edb in execute_ex (ex=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:429
#54 0x000055762811bf74 in zend_execute (op_array=0x7f6555a67000, op_array@entry=0x7f64f0edbe88,
return_value=return_value@entry=0x7f6555a13550) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend_vm_execute.h:474
#55 0x0000557628083e44 in zend_execute_scripts (type=type@entry=8, retval=0x7f6555a13550,
retval@entry=0x0, file_count=file_count@entry=3) at
/build/php7.1-zUmk8m/php7.1-7.1.9/Zend/zend.c:1480
#56 0x00005576280234a8 in php_execute_script (primary_file=0x7ffe4c966f90) at
/build/php7.1-zUmk8m/php7.1-7.1.9/main/main.c:2552
#57 0x0000557627f0c4ac in main (argc=<optimized out>, argv=<optimized out>) at
/build/php7.1-zUmk8m/php7.1-7.1.9/sapi/fpm/fpm/fpm_main.c:1966
Excerpt of zbacktrace
(gdb) zbacktrace
[0x7f6555a14070] Generator->send(object[0x7f6555a140c0]) [internal function]
[0x7f6555a13fd0]
rg\core\pow\preparer\handler\GeneratorHandler->returnResponse(object[0x7f6555a14020],
object[0x7f6555a14030], reference)
/home/researchgate/community/tor_prd/blue/src/core/pow/preparer/handler/GeneratorHandler.php:60
[0x7f6555a13f40]
rg\core\pow\preparer\handler\PreparableHandler->returnResponse(object[0x7f6555a13f90],
object[0x7f6555a13fa0], array(1)[0x7f6555a13fb0])
/home/researchgate/community/tor_prd/blue/src/core/pow/preparer/handler/PreparableHandler.php:82
...
the code of returnResponse in GeneratorHandler looks rather innocent:
public function returnResponse($preparable, \Traversable $iterator, array $data) {
if (!is_array($iterator->rawCurrent()) && count($data) === 1) {
$data = reset($data);
}
$preparable->send($data);
}
The reason why I'm suspecting it has something to do with a fatal error is that it seems to go
through this line https://github.com/php/php-src/blob/PHP-7.1.9/Zend/zend_generators.c#L133
in the bt
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75351&edit=1