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
Tracing JIT: segfault when a trace runs out of side exits (switch with ~500 cases followed by ++$a) #24388
With the tracing JIT, a hot function containing a switch with about 500 cases followed by ++$a crashes PHP at JIT-compile time (SIGSEGV in a release build, assertion failure in a debug build).
A testing tool found this; it is not from a real program. The 11 KB reproducer is generated (507 cases; the case count matters, 480-506 and 511-530 do not trigger it with this shape):
I expected the JIT to give up on the trace (TOO_MANY_EXITS) and the script to finish normally, as it does with opcache.jit=off (exit 0).
It reproduces at 5ccc56b: the debug build aborts with the assertion above (exit 134), the release build segfaults (exit 139) with no output.
Looks like zend_jit_inc_dec() in ext/opcache/jit/zend_jit_ir.c does not check the result of zend_jit_trace_get_exit_addr(), which is NULL once the trace has used its ZEND_JIT_TRACE_MAX_EXITS (512) exits, so it emits a guard to address 0; the neighbouring code does if (!exit_addr) return 0;. Open PR #18392 may be related; I did not test it.
I can send a patch if that helps.
Found with an LLM-based testing tool; I used Claude to reduce it and look for the cause.
Activity
Fix phpGH-24388: Tracing JIT segfault when a trace runs out of side e…
Merge branch 'PHP-8.4' into PHP-8.5
Merge branch 'PHP-8.5' into PHP-8.6
Merge branch 'PHP-8.6'