Segmentation fault during request shutdown when memory limit is exceeded during closure initialization #12073
Closed
Description
Description
The following code:
<?php
class Wrapper {
private $cb;
public function __construct( callable $cb ) {
$this->cb = $cb;
}
}
class Dep {
public function test() {
echo "test";
}
}
class ClosureTest {
public function __construct(
private Dep $dep,
private Dep $dep2,
private Dep $dep3,
private Dep $dep4,
private Dep $dep5,
private Dep $dep6
) {
}
private function output( $i, $k ) {
echo $i . $k;
}
function create( int $i, int $k = 213 ) {
return new Wrapper( function ( $j ) use ( $k ) {
$this->output( $j, $k );
$this->dep->test();
$this->dep2->test();
$this->dep3->test();
$this->dep4->test();
$this->dep5->test();
$this->dep6->test();
} );
}
}
ini_set( 'memory_limit', '4875K' );
$test = new ClosureTest( new Dep(), new Dep(), new Dep(), new Dep(), new Dep(), new Dep() );
for ( $i = 0; $i < 10_000; $i++ ) {
$$i = $test->create( $i );
}
reliably segfaults on PHP 8.2, 8.1. and 8.0 with opcache enabled (-dopcache.enable_cli=1
).
This is a simplified reproducer—originally seen on PHP 8.0.30, in the FPM SAPI, for a request that hit its configured memory limit on a line of code instantiating a closure: https://github.com/wikimedia/mediawiki/blob/f071c22a9a3e7e399dcf3256c96a952f15291a69/includes/Revision/RevisionStore.php#L1786
There is no segmentation fault if Opcache is disabled.
Backtrace of that original error:
#0 zend_mm_free_heap (ptr=0x7631, heap=0x7ff6cb600040) at /usr/src/php/Zend/zend_alloc.c:1366
#1 _efree (ptr=0x7631) at /usr/src/php/Zend/zend_alloc.c:2551
#2 0x0000559226f12314 in destroy_op_array (op_array=0x7ff6639fc778) at /usr/src/php/Zend/zend_opcode.c:475
#3 0x0000559226f94ec9 in zend_closure_free_storage (object=0x7ff6639fc740) at /usr/src/php/Zend/zend_closures.c:490
#4 0x0000559226fa45aa in zend_objects_store_free_object_storage (objects=objects@entry=0x559227c220c8 <executor_globals+840>,
fast_shutdown=fast_shutdown@entry=true) at /usr/src/php/Zend/zend_objects_API.c:104
#5 0x0000559226f0df3f in shutdown_executor () at /usr/src/php/Zend/zend_execute_API.c:339
#6 0x0000559226f1d4a9 in zend_deactivate () at /usr/src/php/Zend/zend.c:1239
#7 0x0000559226eb8559 in php_request_shutdown (dummy=dummy@entry=0x0) at /usr/src/php/main/main.c:1854
#8 0x0000559226c42b8a in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/php/sapi/fpm/fpm/fpm_main.c:1942
PHP Version
PHP 8.2.9
Operating System
No response