Skip to content
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

Segfault in zend_accel_class_hash_copy #9164

Closed
turchanov opened this issue Jul 27, 2022 · 2 comments · Fixed by #9188
Closed

Segfault in zend_accel_class_hash_copy #9164

turchanov opened this issue Jul 27, 2022 · 2 comments · Fixed by #9188

Comments

@turchanov
Copy link
Contributor

Description

We use php-fpm with opcache with filecache, no JIT. On deployment of a newer version of php application codebase (that is opcache filecache is empty at the moment) we experience a spike of segfaults in php-fpm workers. This bug seems to be relevant to https://bugs.php.net/bug.php?id=81607 as we see that ce->name->gc->refcount / 8 is beyond the limits of CG(map_ptr_last)

#0  0x00007fd7b8a9e67a in zend_accel_class_hash_copy (target=0x26aa520, source=0x47dc6cf0)
    at /usr/src/debug/php-8.1.8-debug/ext/opcache/zend_accelerator_util_funcs.c:210
#1  0x00007fd7b8a9e870 in zend_accel_load_script (persistent_script=0x47dc6bc0, from_shared_memory=1)
    at /usr/src/debug/php-8.1.8-debug/ext/opcache/zend_accelerator_util_funcs.c:230
#2  0x00007fd7b8a6a2d8 in persistent_compile_file (file_handle=0x7ffd3264a1b0, type=2)
    at /usr/src/debug/php-8.1.8-debug/ext/opcache/ZendAccelerator.c:2240
#3  0x000000000099e6bf in compile_filename (type=2, filename=0x426aac80) at /usr/src/debug/php-8.1.8-debug/Zend/zend_language_scanner.c:707
#4  0x0000000000a7886c in zend_include_or_eval (inc_filename_zv=0x7fd7b4015ac0, type=2)
    at /usr/src/debug/php-8.1.8-debug/Zend/zend_execute.c:4617
(gdb) fr 0
   |204                     } else {
   |205                             zend_class_entry *ce = Z_PTR(p->val);
   |206                             t = _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1);
   |207                             if ((ce->ce_flags & ZEND_ACC_LINKED)
   |208                              && ZSTR_HAS_CE_CACHE(ce->name)
   |209                              && ZSTR_VAL(p->key)[0]) {
  >|210                                     ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0);  <----
   |211                             }
   |212                     }

(gdb) print compiler_globals->map_ptr_base
$1 = (void *) 0x7fd7a7a6000f

(gdb) print compiler_globals->map_ptr_last
$2 = 57332

(gdb) print ce->name->gc->refcount
$3 = 472001

(gdb) print ce->name->gc->refcount / 8
$4 = 59000

We implemented a work-around by reverting ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0) to ZSTR_SET_CE_CACHE(ce->name, ce) in zend_accel_class_hash_copy (and in zend_accel_inheritance_cache_get and zend_persist_class_entry just in case) as it appears that invalid cache pointers do exists at this point. With this fix segfauls do not happen anymore.

opcache settings:

zend_extension=opcache.so
opcache.enable = 1
opcache.max_accelerated_files = 50000
opcache.interned_strings_buffer = 50
opcache.memory_consumption = 320
opcache.revalidate_freq = 15
opcache.enable_file_override = 1
opcache.file_cache = "..."

PHP Version

PHP 8.1.8

Operating System

CentOS 7.7

@turchanov
Copy link
Contributor Author

This bug also happens in 8.1.6. This is the first version of 8.1.x series on which we tried to run our production load.

@arnaud-lb
Copy link
Member

Fixed #9188. Thank you for the high quality bug report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants