[php-src] PR #24487: Fix temporaries leaking when a VM interrupt throws at the op that fre…

From: Date: Wed, 21 Oct 2026 17:30:45 +0000
Subject: [php-src] PR #24487: Fix temporaries leaking when a VM interrupt throws at the op that fre…
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39664@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24487 Author: cscott The VM checks for interrupts after setting opline to the next op, such as a jump target (and, in the CALL VM, the op after a call to a user function); the JIT checks at loop headers and in side-exit stubs. If the interrupt function throws (async pcntl signal handler, Excimer timeout, ...), the exception is attributed to that op, which has not run. Live ranges end at the op that consumes a var, so ZEND_HANDLE_EXCEPTION does not free vars that this op was about to consume: ```php function gen() { yield 1; release(); } // interrupt pending as release() returns foreach (gen() as $v) {} // FE_FETCH jumps to FE_FREE: generator leaks ``` The same happens with switch on a string, and with ternary/match results assigned after the jump. The interrupt helpers already undefine the result of the interrupted op. This PR moves that to zend_cleanup_interrupted_op(), which also frees vars whose live range ends at the interrupted op, and the operand defined by the op just before it (which has no live range). Interrupt timing is unchanged. Tests use zend_test.observer.set_vm_interrupt_on_end (also added by the fix for GH-24480), which makes an interrupt pending and throwing as an observed function returns. Tested on debug builds of the hybrid and CALL VMs, without opcache and with opcache with JIT off, function JIT and tracing JIT.

« previous php.git-pulls (#39664) next »