Repository navigation
Description
Description
The built-in server (php -S, PHP_CLI_SERVER_WORKERS=4) running the web API tests of a Magento 2.4.9 app segfaults now and then on GitHub Actions. It always happens on the first request that places an order, when pelago/emogrifier does new Sabberworm\CSS\RuleSet\DeclarationBlock() to inline the e-mail CSS.
It only happens with the tracing JIT on. Same commit, REST suite only:
| opcache | jit | runs | crashes |
|---|---|---|---|
| on | 1235, 256M buffer |
20 | 3 |
| on | disable |
20 | 0 |
| off | - | 5 | 0 |
All three crashes left a core, and in each one a worker faults at the same place:
#0 ZEND_NEW_SPEC_CONST_UNUSED_HANDLER Zend/zend_vm_execute.h:11321
#1 execute_ex
#2 zend_call_function
#3 zif_call_user_func_array
#4 execute_ex
#5 zend_call_function
#6 zif_call_user_func
#7 execute_ex
#8 zend_execute_script
#9 php_cli_server_dispatch_router
The faulting instruction is call *0x80(%rax) with rax = NULL, i.e. obj->handlers->get_constructor. The class entry of DeclarationBlock is a linked user class (type = 2, ce_flags = 0x441208) with create_object = NULL and default_object_handlers = NULL, so the new object gets handlers == NULL.
In one run a second worker died 8 seconds later inside the JIT:
#0 zend_jit_cleanup_func_info ext/opcache/jit/zend_jit.c:3017
#1 zend_jit_cleanup_func_info ext/opcache/jit/zend_jit.c:3041
#2 zend_real_jit_func (trigger=3)
#3 zend_jit_hot_func ext/opcache/jit/zend_jit.c:3234
I can't reproduce it locally with the same binary and ini (12 cold runs of the crashing test class with the JIT on), and I don't have a standalone script. Not sure whether it is related to GH-24488, which is also an 8.5.12 heap regression; Magento uses SimpleXML heavily. I still have the cores and the matching dbgsym, and can run extra debug steps in CI if that helps.
Setup:
- Build: shivammathur/setup-php
php_8.5-nts+ubuntu26.04.tar.zstwith the matching dbgsym,ini-file: production,memory_limit=-1. setup-php addsopcache.enable=1,opcache.jit=1235andopcache.jit_buffer_size=256M; the other OPcache settings are defaults. - Server:
php -d memory_limit=2G -S 127.0.0.1:8080 -t pub phpserver/router.php - Kernel:
php[5660]: segfault at 80 ip 0000636e24b978d3 sp 00007ffdb9dc98d0 error 4 in php8.5[5978d3,636e24746000+503000]
Loaded extensions
amqp apcu ast bcmath bz2 calendar Core ctype curl date dba dom ds enchant exif FFI fileinfo filter ftp gd gettext gmp hash iconv igbinary imagick imap intl json ldap lexbor libxml mbstring memcache memcached mongodb msgpack mysqli mysqlnd odbc openssl pcntl pcre PDO pdo_dblib PDO_Firebird pdo_mysql PDO_ODBC pdo_pgsql pdo_sqlite pdo_sqlsrv pgsql Phar posix random readline redis Reflection session shmop SimpleXML snmp soap sockets sodium SPL sqlite3 sqlsrv standard sysvmsg sysvsem sysvshm tidy tokenizer uri xml xmlreader xmlwriter xsl yaml Zend OPcache zip zlib zmq
PHP Version
PHP 8.5.12 (cli) (built: Oct 24 2026 12:37:40) (NTS)
Zend Engine v4.5.12, with Zend OPcache v8.5.12
Operating System
Ubuntu 26.04 (GitHub-hosted ubuntu-latest), x86_64
Activity
iliaal commentedon Oct 31, 2026
Duplicate of #24577. A shared interned class-name string can get IS_STR_CLASS_NAME_MAP_PTR set visible to a concurrent worker before its map_ptr offset lands in gc.refcount; the cold-cache worker then reads refcount 2 as the CE-cache slot and instantiates a garbage ce. Here that ce had NULL handlers, so it faulted one deref later in ZEND_NEW at obj->handlers->get_constructor instead of inside GET_CE_CACHE. Your multi-worker
php -Sover OPcache SHM is the same cold-cache, two-children-compiling race as the FPM report.Fixed in 47d5c0c (#24585), merged Oct 27; your Oct 24 nightly predates it (it carries the GH-24488 fix, not this one). The tracing JIT only widens the window. Please retest on an 8.5 build after Oct 27 / 8.5.13.
ci(behat): disable CLI OPcache and JIT in integration tests