[php-src] PR #24200: Bug: GC of a fiber suspended in a file included from a function
| From: | EdmondDantes | Date: | Thu, 08 Oct 2026 19:26:15 +0000 |
| Subject: | [php-src] PR #24200: Bug: GC of a fiber suspended in a file included from a function | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-39266@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/24200
Author: EdmondDantes
A file included from a function, or code eval'd in it, runs in its own frame over the symbol
table of that function.
zend_fiber_object_gc() walks the suspended fiber's frames
and adds the symbol table of each one, so a fiber suspended inside such a file added the same table
twice: the collector counted its values twice and decremented their refcounts below zero.
Reproduction (debug build, no extensions):
```php
// inc.php: $local = new stdClass; Fiber::suspend(); echo "kept\n";
function run() { include __DIR__ . '/inc.php'; }
$fiber = new Fiber(function () { run(); });
$fiber->start();
$holder = new stdClass;
$holder->fiber = $fiber;
$holder->self = $holder;
unset($holder);
gc_collect_cycles();
$fiber->resume();
```
Expected: kept. Actual: zend_gc_delref: Assertion 'p->refcount >
0' failed (debug build).
The fix skips a frame whose symbol table is the one the previous frame already added. No behaviour
change otherwise.
Test: Zend/tests/fibers/gc-include-shared-symbol-table.phpt (aborts on PHP-8.4 debug
without the fix, passes with it; Zend/tests/fibers 97 of 97 pass). The test relies on
the debug assertion, so only debug builds detect the bug.