mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: [ci skip] NEWS for GH-16025 Fix assertion failure in generator dtor (#16025)
This commit is contained in:
commit
7e6616cafb
3 changed files with 59 additions and 20 deletions
53
Zend/tests/gh15866.phpt
Normal file
53
Zend/tests/gh15866.phpt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
--TEST--
|
||||||
|
GH-15866: Core dumped in Zend/zend_generators.c
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Canary {
|
||||||
|
public function __construct(public mixed $value) {}
|
||||||
|
public function __destruct() {
|
||||||
|
printf("%s\n", __METHOD__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
Fiber::suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
function f($canary) {
|
||||||
|
try {
|
||||||
|
var_dump(yield from g());
|
||||||
|
} finally {
|
||||||
|
print "Generator finally\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$canary = new Canary(null);
|
||||||
|
$iterable = f($canary);
|
||||||
|
$fiber = new Fiber(function () use ($iterable, $canary) {
|
||||||
|
try {
|
||||||
|
$iterable->next();
|
||||||
|
} finally {
|
||||||
|
print "Fiber finally\n";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$canary->value = $fiber;
|
||||||
|
$fiber->start();
|
||||||
|
|
||||||
|
// Reset roots
|
||||||
|
gc_collect_cycles();
|
||||||
|
|
||||||
|
// Add to roots, create garbage cycles
|
||||||
|
$fiber = $iterable = $canary = null;
|
||||||
|
|
||||||
|
print "Collect cycles\n";
|
||||||
|
gc_collect_cycles();
|
||||||
|
|
||||||
|
?>
|
||||||
|
==DONE==
|
||||||
|
--EXPECT--
|
||||||
|
Collect cycles
|
||||||
|
Canary::__destruct
|
||||||
|
Generator finally
|
||||||
|
Fiber finally
|
||||||
|
==DONE==
|
|
@ -218,43 +218,30 @@ static zend_always_inline void clear_link_to_root(zend_generator *generator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In the context of zend_generator_dtor_storage during shutdown, check if
|
/* Check if the node 'generator' is running in a fiber */
|
||||||
* the intermediate node 'generator' is running in a fiber */
|
|
||||||
static inline bool check_node_running_in_fiber(zend_generator *generator) {
|
static inline bool check_node_running_in_fiber(zend_generator *generator) {
|
||||||
ZEND_ASSERT(EG(flags) & EG_FLAGS_IN_SHUTDOWN);
|
|
||||||
ZEND_ASSERT(generator->execute_data);
|
ZEND_ASSERT(generator->execute_data);
|
||||||
|
|
||||||
if (generator->flags & ZEND_GENERATOR_IN_FIBER) {
|
if (EXPECTED(generator->flags & ZEND_GENERATOR_IN_FIBER)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator->node.children == 0) {
|
if (EXPECTED(generator->node.children == 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generator->flags & ZEND_GENERATOR_DTOR_VISITED) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
generator->flags |= ZEND_GENERATOR_DTOR_VISITED;
|
|
||||||
|
|
||||||
if (generator->node.children == 1) {
|
if (generator->node.children == 1) {
|
||||||
if (check_node_running_in_fiber(generator->node.child.single)) {
|
return check_node_running_in_fiber(generator->node.child.single);
|
||||||
goto in_fiber;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_generator *child;
|
zend_generator *child;
|
||||||
ZEND_HASH_FOREACH_PTR(generator->node.child.ht, child) {
|
ZEND_HASH_FOREACH_PTR(generator->node.child.ht, child) {
|
||||||
if (check_node_running_in_fiber(child)) {
|
if (check_node_running_in_fiber(child)) {
|
||||||
goto in_fiber;
|
return true;
|
||||||
}
|
}
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
return false;
|
|
||||||
|
|
||||||
in_fiber:
|
return false;
|
||||||
generator->flags |= ZEND_GENERATOR_IN_FIBER;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||||
|
|
|
@ -95,7 +95,6 @@ static const uint8_t ZEND_GENERATOR_FORCED_CLOSE = 0x2;
|
||||||
static const uint8_t ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
|
static const uint8_t ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
|
||||||
static const uint8_t ZEND_GENERATOR_DO_INIT = 0x8;
|
static const uint8_t ZEND_GENERATOR_DO_INIT = 0x8;
|
||||||
static const uint8_t ZEND_GENERATOR_IN_FIBER = 0x10;
|
static const uint8_t ZEND_GENERATOR_IN_FIBER = 0x10;
|
||||||
static const uint8_t ZEND_GENERATOR_DTOR_VISITED = 0x20;
|
|
||||||
|
|
||||||
void zend_register_generator_ce(void);
|
void zend_register_generator_ce(void);
|
||||||
ZEND_API void zend_generator_close(zend_generator *generator, bool finished_execution);
|
ZEND_API void zend_generator_close(zend_generator *generator, bool finished_execution);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue