Closed
Description
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