Fix "Opcache breaks autoloading after E_COMPILE_ERROR" #8297
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.
Fixes GH-8063 (may also fix GH-8164, GH-8358)
Recorded errors may be attached to the wrong cached script when a fatal error occurs during recording. This happens because the fatal error will cause a bailout, which may prevent the recorded errors from being cleared. If a script is compiled after bailout (or a class is linked or bound), the recorded errors will be attached to it and cached.
More specifically,
zend_do_link_class
may enable error recording, but will not clear recorded errors if a bailout happens. This can also happen inzend_try_early_bind
.preload_link
andopcache_compile_file
prevent this by usingzend_try
.In this change I also use
zend_try
inzend_do_link_class
andzend_try_early_bind
to ensure that recorded errors are cleared before bailout.I was not sure about the overhead of
zend_try
, so I ran some benchmarks:With opcache: https://gist.github.com/arnaud-lb/fa42613d7c18061e0eaf64c3593d1e84
Without opcache: https://gist.github.com/arnaud-lb/c10841d190113e25bdacfdf44b0bd513
patch1 is this PR, patch0 is a different implementation that clears recorded errors in php_call_shutdown_functions instead of using zend_try.
link_class and bind_class are micro benchmarks for zend_do_link_class and zend_try_early_bind (here and here, respectively). I couldn't obtain stable results for these. The results are more dependent on the order of the PHP versions. than anything else.
The Symfony demo app benchmark shows no significant difference.