mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix printing backtrace of fake generator frame
This commit is contained in:
commit
a58df54bc4
3 changed files with 38 additions and 0 deletions
27
Zend/tests/generators/gh15851.phpt
Normal file
27
Zend/tests/generators/gh15851.phpt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
--TEST--
|
||||||
|
GH-15851: Access on NULL when printing backtrace with freed generator
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
public function __destruct() {
|
||||||
|
debug_print_backtrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bar() {
|
||||||
|
yield from foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function foo() {
|
||||||
|
$foo = new Foo();
|
||||||
|
yield;
|
||||||
|
}
|
||||||
|
|
||||||
|
$gen = bar();
|
||||||
|
foreach ($gen as $dummy);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
#0 %s(%d): Foo->__destruct()
|
||||||
|
#1 %s(%d): bar()
|
|
@ -1883,6 +1883,16 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
|
||||||
}
|
}
|
||||||
|
|
||||||
while (call && (limit == 0 || frameno < limit)) {
|
while (call && (limit == 0 || frameno < limit)) {
|
||||||
|
if (UNEXPECTED(!call->func)) {
|
||||||
|
/* This is the fake frame inserted for nested generators. Normally,
|
||||||
|
* this frame is preceded by the actual generator frame and then
|
||||||
|
* replaced by zend_generator_check_placeholder_frame() below.
|
||||||
|
* However, the frame is popped before cleaning the stack frame,
|
||||||
|
* which is observable by destructors. */
|
||||||
|
call = zend_generator_check_placeholder_frame(call);
|
||||||
|
ZEND_ASSERT(call->func);
|
||||||
|
}
|
||||||
|
|
||||||
zend_execute_data *prev = call->prev_execute_data;
|
zend_execute_data *prev = call->prev_execute_data;
|
||||||
|
|
||||||
if (!prev) {
|
if (!prev) {
|
||||||
|
|
|
@ -1045,6 +1045,7 @@ do_repeat:
|
||||||
object_init_ex(&ref, pce);
|
object_init_ex(&ref, pce);
|
||||||
|
|
||||||
memset(&execute_data, 0, sizeof(zend_execute_data));
|
memset(&execute_data, 0, sizeof(zend_execute_data));
|
||||||
|
execute_data.func = (zend_function *) &zend_pass_function;
|
||||||
EG(current_execute_data) = &execute_data;
|
EG(current_execute_data) = &execute_data;
|
||||||
zend_call_known_instance_method_with_1_params(
|
zend_call_known_instance_method_with_1_params(
|
||||||
pce->constructor, Z_OBJ(ref), NULL, &arg);
|
pce->constructor, Z_OBJ(ref), NULL, &arg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue