You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Delayed OOM raised during compilation is dropped when compilation fails #24631
If the main script exceeds memory_limit while being compiled and compilation then fails, the memory error is never reported. The parse error is reported instead. zend_execute_script() only handles a pending delayed OOM when zend_compile_file() returns an op_array:
@bhaak found the same problem in sapi/fuzzer/fuzzer-sapi.c: 31c0ea7#r206151500. Their fix also applies here: handle the delayed OOM outside the if (op_array) block.
When an allocation fails, OOM is set to PENDING with message/filename/lineno stored
zend_handle_delayed_oom() is supposed to be called at a safe point to report the error
The issue described here — OOM raised during zend_compile_file() but parse error reported instead — suggests that the safe-point check in zend_execute_script() only fires when compilation succeeds (returns an op_array). If compilation fails, the pending OOM in EG(delayed_oom) is never consumed — it stays at PENDING or gets reset without being reported.
Looking at the state machine, the reset points are:
main/main.c:1877 (start of request shutdown — state = NONE)
main/main.c:1972 (after shutdown_memory_manager — state = NONE)
If the compilation-failure path reaches one of these resets before zend_handle_delayed_oom() gets a chance to report, the OOM is silently swallowed — which matches what you're seeing.
Possible fix direction: call zend_handle_delayed_oom() in the compilation-failure path of zend_execute_script() (alongside or before the parse error report), or make the reset points check-and-report before clearing.
(We reverse-engineered this machinery while investigating the related allocation-failure paths in #24563 — happy to share more detail if useful.)
Activity
srayuth089 commentedon Oct 25, 2026
Quick mechanism note that might help triage: this looks like a gap in the delayed-OOM state machine introduced in 3584a98.
The fix's design (per our reading of
zend_alloc.h/zend_execute_API.cin that commit):EG(delayed_oom)transitions NONE → PENDING → HANDLING → HANDLEDzend_handle_delayed_oom()is supposed to be called at a safe point to report the errorThe issue described here — OOM raised during
zend_compile_file()but parse error reported instead — suggests that the safe-point check inzend_execute_script()only fires when compilation succeeds (returns an op_array). If compilation fails, the pending OOM inEG(delayed_oom)is never consumed — it stays at PENDING or gets reset without being reported.Looking at the state machine, the reset points are:
zend.c:814(executor init —memsetclearsdelayed_oom)main/main.c:1877(start of request shutdown —state = NONE)main/main.c:1972(aftershutdown_memory_manager—state = NONE)If the compilation-failure path reaches one of these resets before
zend_handle_delayed_oom()gets a chance to report, the OOM is silently swallowed — which matches what you're seeing.Possible fix direction: call
zend_handle_delayed_oom()in the compilation-failure path ofzend_execute_script()(alongside or before the parse error report), or make the reset points check-and-report before clearing.(We reverse-engineered this machinery while investigating the related allocation-failure paths in #24563 — happy to share more detail if useful.)