Skip to content

Extend map_ptr before copying class table #9188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 1, 2022
Merged

Conversation

arnaud-lb
Copy link
Member

A script loaded from shared memory may reference map_ptr entries higher than CG(map_ptr_last), so we may need to extend the map_ptr before loading the script.

zend_accel_load_script() does a zend_map_ptr_extend(ZCSG(map_ptr_last)), but I believe that it does it too late. In this change I move the zend_map_ptr_extend(ZCSG(map_ptr_last)) before anything else in zend_accel_load_script(). I moved the whole if (EXPECTED(from_shared_memory)) { block up to avoid duplicating the condition.

Fixes #9164

I understand that map_ptr is what allows opcache structures to be immutable, and to be used directly from SHM without copy. Each php process has a local mutable map_ptr vector, in which opcache structures can reference elements by index. The opcache can allocate new map_ptr indices in one process, but other processes need to extend the vector themselves.

Comment on lines 350 to +353
if (EXPECTED(from_shared_memory)) {
if (ZCSG(map_ptr_last) > CG(map_ptr_last)) {
zend_map_ptr_extend(ZCSG(map_ptr_last));
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is just moving the if (EXPECTED(from_shared_memory)) { block to the beginning of the function, and the if (ZCSG(map_ptr_last) > CG(map_ptr_last)) { block at the beginning of the block.

@arnaud-lb arnaud-lb changed the title Extended map_ptr before copying class table Extend map_ptr before copying class table Jul 28, 2022
@arnaud-lb arnaud-lb requested a review from dstogov July 30, 2022 13:14
@@ -743,6 +743,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {

#define ZSTR_SET_CE_CACHE_EX(s, ce, validate) do { \
if (!(validate) || ZSTR_VALID_CE_CACHE(s)) { \
ZEND_ASSERT((validate) || ZSTR_VALID_CE_CACHE(s)); \
Copy link
Member

Choose a reason for hiding this comment

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

I didn't understand what do you do with this assertion

Copy link
Member

Choose a reason for hiding this comment

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

It's asserting that the ce cache is valid, even if validation is skipped.

Copy link
Member

@dstogov dstogov left a comment

Choose a reason for hiding this comment

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

Looks fine

@arnaud-lb arnaud-lb merged commit a697083 into php:master Aug 1, 2022
arnaud-lb added a commit that referenced this pull request Aug 1, 2022
arnaud-lb added a commit that referenced this pull request Aug 1, 2022
* PHP-8.1:
  [ci skip] NEWS
  Extended map_ptr before copying class table (#9188)
HypeMC added a commit to HypeMC/php-src that referenced this pull request Dec 8, 2022
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.

Segfault in zend_accel_class_hash_copy
3 participants