From c531f3d79b1ddbddc04fe3a5b5f51e8d9c2f36d4 Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Sat, 15 Mar 2025 12:18:08 +0100 Subject: [PATCH] Disable ZEND_RC_MOD_CHECK() while loading shared extension in FPM This fixes a ZEND_RC_MOD_CHECK() assertion failure when building with "-DZEND_RC_DEBUG=1 --enable-debug --enable-zts". php_dl() is called after startup, and manipulates the refcount of persistent strings, which is not allowed at this point of the lifecycle. The dl() function disables the ZEND_RC_MOD_CHECK() assertion before calling php_dl(). This change applies the same workaround in FPM. Closes GH-18075 --- sapi/fpm/fpm/fpm_php.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index b88c47671a1..2463f4351b6 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -93,7 +93,21 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */ if (!strcmp(name, "extension") && *value) { zval zv; zend_interned_strings_switch_storage(0); + +#if ZEND_RC_DEBUG + bool orig_rc_debug = zend_rc_debug; + /* Loading extensions after php_module_startup() breaks some invariants. + * For instance, it will update the refcount of persistent strings, + * which is normally not allowed at this stage. */ + zend_rc_debug = false; +#endif + php_dl(value, MODULE_PERSISTENT, &zv, 1); + +#if ZEND_RC_DEBUG + zend_rc_debug = orig_rc_debug; +#endif + zend_interned_strings_switch_storage(1); return Z_TYPE(zv) == IS_TRUE ? FPM_PHP_INI_EXTENSION_LOADED : FPM_PHP_INI_EXTENSION_FAILED; }