Repository navigation
Conversation
…opline Assisted-by: Claude
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here is the patch I offered in the issue, thanks for the go-ahead.
When the tracing JIT inlines a call (
ZEND_JIT_TRACE_ENTER) and some of the callee's CVs are register-allocated withZREG_LOADand stillMAY_BE_GUARD, it emits a type guard for them with a NULL opline. A NULL exit opline means "EX(opline) is already valid", but at this point the frame is the freshly pushed callee whose EX(opline) has not been written yet. So when the guard fails (here: the reference-bound arguments are ints while the trace is recorded and floats on a later call),zend_jit_trace_exit()resumes the VM at a garbage opline. A debug build trips the opline assertion; a release build segfaults (as reported in the issue).The fix passes
(p+1)->opline, the callee's first traced opline, the same opline the SEND_UNPACK/SEND_ARRAY guard just above uses. A failing guard then exits to the start of the callee instead.The test
ext/opcache/tests/jit/gh24389.phptis the reproducer from the issue, plus a check of the return values. On a PHP-8.4 debug ASan build it fails thezend_jit_trace_exitassertion without the fix and passes with it. The issue's reproducer and itsforeachby-reference variant now run to completion, and the variant prints the same as with the JIT off. With the fix,ext/opcache/testshas the same three failures under the tracing and the function JIT (gh9259_003, preload_parse_error, log_verbosity_bug). They are LeakSanitizer reports from this ASan build, and they fail the same way without the fix under the tracing JIT.Fixes #24389.
Found with an LLM-based testing tool; I wrote this fix with help from Claude and reviewed it myself.