Skip to content

Set zend_rc_debug=false before loading shared ext in FPM config #18075

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

Closed
wants to merge 1 commit into from

Conversation

arnaud-lb
Copy link
Member

@arnaud-lb arnaud-lb commented Mar 15, 2025

This fixes the following nightly failure: https://github.com/php/php-src/actions/runs/13868159277/job/38811107321. This is triggered by #17961, but the root issue was pre-existing.

The test sapi/fpm/tests/gh9921-php-value-ext-mod-handlers.phpt fails an assertion in ZEND_RC_MOD_CHECK() here:

php-src/Zend/zend_types.h

Lines 1322 to 1325 in 45c7e3b

static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) {
ZEND_RC_MOD_CHECK(p);
return ++(p->refcount);
}

when trying to copy the property name here:

name = zend_new_interned_string(zend_string_copy(name));

The property name is a persistent string created here:

zend_string *property_a_name = zend_string_init("a", sizeof("a") - 1, 1);

Backtrace:

#7  0x0000560e0f8d1f0e in zend_gc_addref (p=0x560e2816a5e0) at /php-src/Zend/zend_types.h:1323
#8  0x0000560e0f8d239c in zend_string_copy (s=0x560e2816a5e0) at /php-src/Zend/zend_string.h:217
#9  0x0000560e0f8e40dc in zend_declare_typed_property (ce=0x560e28112ec0, name=0x560e2816a5e0, property=0x7ffeb5fa7e70, access_type=1, doc_comment=0x0, type=...) at /php-src/Zend/zend_API.c:4421
#10 0x00007fb1320dead7 in register_class_DlTestSuperClass () at /php-src/ext/dl_test/dl_test_arginfo.h:70
#11 0x00007fb1320df2ef in zm_startup_dl_test (type=1, module_number=70) at /php-src/ext/dl_test/dl_test.c:108
#12 0x0000560e0f8dc182 in zend_startup_module_ex (module=0x7fb1320e2140 <dl_test_module_entry>) at /php-src/Zend/zend_API.c:2313
#13 0x0000560e0f6542e2 in php_load_extension (filename=0x560e28163510 "dl_test", type=1, start_now=1) at /php-src/ext/standard/dl.c:257
#14 0x0000560e0f6543b5 in php_dl (file=0x560e28163510 "dl_test", type=1, return_value=0x7ffeb5fa8210, start_now=1) at /php-src/ext/standard/dl.c:300
#15 0x0000560e0fa840d6 in fpm_php_apply_defines_ex (kv=0x560e281634d0, mode=4) at /php-src/sapi/fpm/fpm/fpm_php.c:96
#16 0x0000560e0fa842b4 in fpm_php_apply_defines (wp=0x560e280c5b70) at /php-src/sapi/fpm/fpm/fpm_php.c:137
#17 0x0000560e0fa844c3 in fpm_php_init_child (wp=0x560e280c5b70) at /php-src/sapi/fpm/fpm/fpm_php.c:232
#18 0x0000560e0fa734ef in fpm_child_init (wp=0x560e280c5b70) at /php-src/sapi/fpm/fpm/fpm_children.c:199
#19 0x0000560e0fa73f04 in fpm_children_make (wp=0x560e280c5b70, in_event_loop=1, nb_to_spawn=1, is_debug=0) at /php-src/sapi/fpm/fpm/fpm_children.c:461
#20 0x0000560e0fa73b01 in fpm_children_bury () at /php-src/sapi/fpm/fpm/fpm_children.c:336
#21 0x0000560e0fa7b381 in fpm_postponed_children_bury (ev=0x560e10c2e220 <children_bury_timer>, which=1, arg=0x0) at /php-src/sapi/fpm/fpm/fpm_events.c:58
#22 0x0000560e0fa7c482 in fpm_event_fire (ev=0x560e10c2e220 <children_bury_timer>) at /php-src/sapi/fpm/fpm/fpm_events.c:487
#23 0x0000560e0fa7c3ec in fpm_event_loop (err=0) at /php-src/sapi/fpm/fpm/fpm_events.c:467
#24 0x0000560e0fa72f77 in fpm_run (max_requests=0x7ffeb5fa8528) at /php-src/sapi/fpm/fpm/fpm.c:113
#25 0x0000560e0fa830f8 in main (argc=6, argv=0x7ffeb5fa8ac8) at /php-src/sapi/fpm/fpm/fpm_main.c:1849

This is reproducible with CFLAGS=-DZEND_RC_DEBUG=1 --enable-debug --enable-zts.

Root cause is that php_dl() breaks invariant by manipulating the refcount of persistent strings after startup, which is normally not allowed. This causes ZEND_RC_MOD_CHECK() to fail.

The dl() function disables this check:

#if ZEND_RC_DEBUG
bool orig_rc_debug = zend_rc_debug;
/* FIXME: Loading extensions during the request breaks some invariants. In
* particular, it will create persistent interned strings, which is not
* allowed at this stage. */
zend_rc_debug = false;
#endif

Here I apply the same workaround before calling php_dl() in fpm_php_apply_defines_ex.

@arnaud-lb arnaud-lb marked this pull request as ready for review March 15, 2025 14:37
@arnaud-lb arnaud-lb requested a review from bukka as a code owner March 15, 2025 14:37
@arnaud-lb arnaud-lb closed this in c531f3d Mar 17, 2025
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.

2 participants