Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 75620c6

Browse files
Fix printing backtrace during generator closing
Fixes GH-15851
1 parent 422aa17 commit 75620c6

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

‎Zend/tests/generators/gh15851.phpt‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-15851: Access on NULL when printing backtrace with freed generator
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function __destruct() {
8+
debug_print_backtrace();
9+
}
10+
}
11+
12+
function bar() {
13+
yield from foo();
14+
}
15+
16+
function foo() {
17+
$foo = new Foo();
18+
yield;
19+
}
20+
21+
$gen = bar();
22+
foreach ($gen as $dummy);
23+
24+
?>
25+
--EXPECTF--
26+
#0 %s(%d): Foo->__destruct()
27+
#1 %s(%d): bar()

‎Zend/zend_builtin_functions.c‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,16 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
17251725
}
17261726

17271727
while (call && (limit == 0 || frameno < limit)) {
1728+
if (UNEXPECTED(!call->func)) {
1729+
/* This is the fake frame inserted for nested generators. Normally,
1730+
* this frame is preceded by the actual generator frame and then
1731+
* replaced by zend_generator_check_placeholder_frame() below.
1732+
* However, the frame is popped before cleaning the stack frame,
1733+
* which is observable by destructors. */
1734+
call = zend_generator_check_placeholder_frame(call);
1735+
ZEND_ASSERT(call->func);
1736+
}
1737+
17281738
zend_execute_data *prev = call->prev_execute_data;
17291739

17301740
if (!prev) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /