Skip to content

Commit 2450724

Browse files
committed
Fix handling of nested generator in zend_test observer
This is the counterpart of phpGH-15952.
1 parent fe51365 commit 2450724

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

Zend/tests/gh16514.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
GH-16514: Nested generator in zend_test observer
3+
--INI--
4+
zend_test.observer.enabled=1
5+
zend_test.observer.show_init_backtrace=1
6+
--FILE--
7+
<?php
8+
9+
class Foo {
10+
public function __destruct() {
11+
debug_print_backtrace();
12+
}
13+
}
14+
function bar() {
15+
yield from foo();
16+
}
17+
function foo() {
18+
$foo = new Foo();
19+
yield;
20+
}
21+
$gen = bar();
22+
foreach ($gen as $dummy);
23+
24+
?>
25+
--EXPECTF--
26+
<!-- init '%sgh16514.php' -->
27+
<!--
28+
{main} %sgh16514.php
29+
-->
30+
<!-- init bar() -->
31+
<!--
32+
bar()
33+
{main} %sgh16514.php
34+
-->
35+
<!-- init foo() -->
36+
<!--
37+
foo()
38+
bar()
39+
{main} %sgh16514.php
40+
-->
41+
<!-- init Foo::__destruct() -->
42+
<!--
43+
Foo::__destruct()
44+
bar()
45+
{main} %sgh16514.php
46+
-->
47+
<!-- init debug_print_backtrace() -->
48+
<!--
49+
debug_print_backtrace()
50+
Foo::__destruct()
51+
bar()
52+
{main} %sgh16514.php
53+
-->
54+
#0 %s(%d): Foo->__destruct()
55+
#1 %s(%d): bar()

ext/zend_test/observer.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "zend_observer.h"
2121
#include "zend_smart_str.h"
2222
#include "ext/standard/php_var.h"
23+
#include "zend_generators.h"
2324

2425
static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execute_data);
2526

@@ -163,6 +164,11 @@ static void observer_show_init_backtrace(zend_execute_data *execute_data)
163164
zend_execute_data *ex = execute_data;
164165
php_printf("%*s<!--\n", 2 * ZT_G(observer_nesting_depth), "");
165166
do {
167+
if (UNEXPECTED(!ex->func)) {
168+
ex = zend_generator_check_placeholder_frame(ex);
169+
ZEND_ASSERT(ex->func);
170+
}
171+
166172
zend_function *fbc = ex->func;
167173
int indent = 2 * ZT_G(observer_nesting_depth) + 4;
168174
if (fbc->common.function_name) {

0 commit comments

Comments
 (0)