Skip to content

Conversation

@dstogov
Copy link
Member

@dstogov dstogov commented May 14, 2019

Opcache reset may remove interned strings, that are used as keys in per-process PCRE caches.
PHP workers clear per-process PCRE cache on startup of next request after opcache reset, but crashes are possible in requests started before the actual reset.

To fix the problem, we reset PCRE caches on request startup, if we see restart pending event.

We also decide, if process may use opcache SHM once, by copying ZCSG(accelerator_enabled) into ZSG(accelerator_enabled) on request startup.

@dstogov
Copy link
Member Author

dstogov commented May 14, 2019

@nikic please take a look.

@dstogov
Copy link
Member Author

dstogov commented May 14, 2019

The originally proposed patch was a bit simpler https://gist.github.com/tony2001/b03b49ab53e0c0c7924cee8bb6b92c61


/* Trivia */
add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && (ZCG(counted) || ZCSG(accelerator_enabled)));
add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && ZCG(accelerator_enabled));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the ZCG(enabled) && part be dropped?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. right.

realpath_cache_clean();

accel_reset_pcre_cache();
ZCG(pcre_reseted) = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what's going on here. The cache is reset in the line above, but pcre_reseted is set to 0. Why is it necessary to reset the cache again?

Copy link
Member

@nikic nikic May 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think I got it. We already finished this restart, so this resets pcre_reseted=0 for the next one.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. We reseted PCRE cache and set ZCG(pcre_reseted) = 1, to avoid multiple resets during restart pending, then reseted once again to repopulated cache with interned keys, and set ZCG(pcre_reseted) = 0 to be prepared for next restart.

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine.

@petk
Copy link
Member

petk commented May 14, 2019

Hello, this has been committed to the repo? Should be closed?

@nikic
Copy link
Member

nikic commented May 14, 2019

For reference: 5c4d125

@mweimerskirch
Copy link

mweimerskirch commented Jun 11, 2019

I'm looking into an issue we're having that might be related to this commit.
On both PHP 7.2.19 and 7.3.6 we now randomly get "PHP Fatal error: require_once(): Failed opening required (...)". The filename in the error message is not always the same, but it's always a file that was included with require_once (but not with require). And it appears only with opcache enabled. We've had this on three different servers. Unfortunately, it's not reproducible. It only appears some times.

Deactivating opcache or going back to 7.2.18 or 7.3.5 "solve" the problem.

Could this be a side effect of this commit?

@nikic
Copy link
Member

nikic commented Jun 11, 2019

@mweimerskirch Yes, this is https://bugs.php.net/bug.php?id=78106. We're trying to figure out what the problem is right now.

@dstogov dstogov deleted the accel_pcre_reset branch October 14, 2019 20:50
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.

4 participants