Skip to content

Fix GH-18847: set EX(opline) when the tracing JIT enters a call frame#22542

Open
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/gh-18847-jit-opline-backtrace
Open

Fix GH-18847: set EX(opline) when the tracing JIT enters a call frame#22542
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/gh-18847-jit-opline-backtrace

Conversation

@iliaal

@iliaal iliaal commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Under the tracing JIT, entering a callee frame doesn't materialize EX(opline) in memory (it stays virtual in the IP register), so a fatal error raised at the frame's first opcode, e.g. an OOM while that opcode pushes its own call frame, makes zend_fetch_debug_backtrace() dereference a NULL opline. The store already existed on the observer path but was gated behind ZEND_OBSERVER_ENABLED; this drops the gate so it also runs with observers off. GH-18899 fixed the function-JIT undefined-variable variant of the same missing-opline class; this is the tracing-JIT call-entry sibling.

This adds one EX(opline) store per JIT call-frame entry (the store observer builds already emit), so flagging in case you'd prefer to narrow it. Fixes #18847

The tracing JIT enters a callee frame without writing EX(opline) to
memory; it keeps the opline in the IP register and writes it back
lazily. When a fatal error is raised before that first store, such as
an out-of-memory while the callee's first opcode pushes its own call
frame, zend_fetch_debug_backtrace() dereferences the NULL EX(opline).
Materialize it at entry, as the observer path already did behind
ZEND_OBSERVER_ENABLED.

Fixes phpGH-18847
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SEGV Zend/zend_builtin_functions.c

1 participant