diff --git a/metadata/supported-configurations.json b/metadata/supported-configurations.json index 20f598cbc02..a205dbcc070 100644 --- a/metadata/supported-configurations.json +++ b/metadata/supported-configurations.json @@ -609,11 +609,14 @@ "default": "false" } ], - "DD_PROFILING_EXPERIMENTAL_IO_ENABLED": [ + "DD_PROFILING_IO_ENABLED": [ { "implementation": "A", "type": "boolean", - "default": "false" + "default": "true", + "aliases": [ + "DD_PROFILING_EXPERIMENTAL_IO_ENABLED" + ] } ], "DD_PROFILING_LOG_LEVEL": [ diff --git a/profiling/src/config.rs b/profiling/src/config.rs index 5cd583d5f45..dddf3a5cb51 100644 --- a/profiling/src/config.rs +++ b/profiling/src/config.rs @@ -2,9 +2,9 @@ use crate::profiling::bindings::zai_config_type::*; use crate::profiling::bindings::{ datadog_php_profiling_copy_string_view_into_zval, ddog_php_prof_config_is_set_by_user, ddog_php_prof_get_memoized_config, zai_config_entry, zai_config_get_value, zai_config_minit, - zai_config_name, zai_config_system_ini_change, zend_ini_entry, zend_long, zend_string, - zend_write, zval, StringError, ZaiStr, IS_FALSE, IS_LONG, IS_TRUE, ZAI_CONFIG_NAME_BUFSIZ, - ZEND_INI_DISPLAY_ORIG, + zai_config_minit_ini_change, zai_config_name, zai_config_system_ini_change, zend_ini_entry, + zend_long, zend_string, zend_write, zval, StringError, ZaiStr, IS_FALSE, IS_LONG, IS_TRUE, + ZAI_CONFIG_NAME_BUFSIZ, ZEND_INI_DISPLAY_ORIG, }; use crate::profiling::zend::zai_str_from_zstr; use crate::profiling::{allocation, bindings}; @@ -415,7 +415,7 @@ pub(crate) enum ConfigId { ProfilingExceptionEnabled, ProfilingExceptionMessageEnabled, ProfilingExceptionSamplingDistance, - ProfilingExperimentalIOEnabled, + ProfilingIOEnabled, ProfilingLogLevel, ProfilingOutputPprof, ProfilingWallTimeEnabled, @@ -450,7 +450,7 @@ impl ConfigId { ProfilingExceptionEnabled => b"DD_PROFILING_EXCEPTION_ENABLED\0", ProfilingExceptionMessageEnabled => b"DD_PROFILING_EXCEPTION_MESSAGE_ENABLED\0", ProfilingExceptionSamplingDistance => b"DD_PROFILING_EXCEPTION_SAMPLING_DISTANCE\0", - ProfilingExperimentalIOEnabled => b"DD_PROFILING_EXPERIMENTAL_IO_ENABLED\0", + ProfilingIOEnabled => b"DD_PROFILING_IO_ENABLED\0", ProfilingLogLevel => b"DD_PROFILING_LOG_LEVEL\0", // Note: this group is meant only for debugging and testing. Please @@ -489,7 +489,7 @@ static DEFAULT_SYSTEM_SETTINGS: SystemSettings = SystemSettings { profiling_exception_enabled: true, profiling_exception_message_enabled: false, profiling_wall_time_enabled: true, - profiling_io_enabled: false, + profiling_io_enabled: true, output_pprof: None, profiling_exception_sampling_distance: 100, profiling_log_level: LevelFilter::Off, @@ -625,11 +625,10 @@ unsafe fn profiling_exception_sampling_distance() -> u32 { /// rinit, and before it is uninitialized in mshutdown. unsafe fn profiling_io_enabled() -> bool { profiling_enabled() - && (profiling_experimental_features_enabled() - || get_system_bool( - ProfilingExperimentalIOEnabled, - DEFAULT_SYSTEM_SETTINGS.profiling_io_enabled, - )) + && get_system_bool( + ProfilingIOEnabled, + DEFAULT_SYSTEM_SETTINGS.profiling_io_enabled, + ) } /// # Safety @@ -1002,6 +1001,9 @@ pub(crate) fn minit(module_number: libc::c_int) { )] }; + const IO_ALIASES: &[ZaiStr] = + unsafe { &[ZaiStr::literal(b"DD_PROFILING_EXPERIMENTAL_IO_ENABLED\0")] }; + // Note that function pointers cannot appear in const functions, so we // can't extract each entry into a helper function. static mut ENTRIES: &mut [zai_config_entry] = unsafe { @@ -1139,13 +1141,13 @@ pub(crate) fn minit(module_number: libc::c_int) { env_config_fallback: None, }, zai_config_entry { - id: transmute::(ProfilingExperimentalIOEnabled), - name: ProfilingExperimentalIOEnabled.env_var_name(), + id: transmute::(ProfilingIOEnabled), + name: ProfilingIOEnabled.env_var_name(), type_: ZAI_CONFIG_TYPE_BOOL, - default_encoded_value: ZaiStr::literal(b"0\0"), - aliases: ptr::null_mut(), - aliases_count: 0, - ini_change: Some(zai_config_system_ini_change), + default_encoded_value: ZaiStr::literal(b"1\0"), + aliases: IO_ALIASES.as_ptr(), + aliases_count: IO_ALIASES.len() as u8, + ini_change: Some(zai_config_minit_ini_change), parser: None, displayer: None, env_config_fallback: None, @@ -1405,6 +1407,7 @@ mod tests { b"DD_PROFILING_TIMELINE_ENABLED\0", "datadog.profiling.timeline_enabled", ), + (b"DD_PROFILING_IO_ENABLED\0", "datadog.profiling.io_enabled"), ( b"DD_PROFILING_EXPERIMENTAL_IO_ENABLED\0", "datadog.profiling.experimental_io_enabled", diff --git a/profiling/tests/phpt/exceptions_01.phpt b/profiling/tests/phpt/exceptions_01.phpt index db537861ee5..429c85ac049 100644 --- a/profiling/tests/phpt/exceptions_01.phpt +++ b/profiling/tests/phpt/exceptions_01.phpt @@ -20,6 +20,7 @@ DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED=no DD_PROFILING_EXPERIMENTAL_EXCEPTION_ENABLED=true DD_PROFILING_EXPERIMENTAL_EXCEPTION_SAMPLING_DISTANCE=20 DD_PROFILING_ALLOCATION_ENABLED=no +DD_PROFILING_IO_ENABLED=no DD_PROFILING_LOG_LEVEL=trace --FILE-- +--INI-- +assert.exception=1 +datadog.profiling.io_enabled=0 +--FILE-- + +--EXPECT-- +Done. diff --git a/profiling/tests/phpt/phpinfo_03.phpt b/profiling/tests/phpt/phpinfo_03.phpt index b0a854c7bcc..4d662c75bd6 100644 --- a/profiling/tests/phpt/phpinfo_03.phpt +++ b/profiling/tests/phpt/phpinfo_03.phpt @@ -50,7 +50,7 @@ $sections = [ ["Experimental CPU Time Profiling Enabled", "false"], ["Allocation Profiling Enabled", "false"], ["Exception Profiling Enabled", "false"], - ["I/O Profiling Enabled", "false"], + ["I/O Profiling Enabled", "true"], ["Endpoint Collection Enabled", "true"], ["Profiling Log Level", "off"], ["Profiling Agent Endpoint", "http://datadog:8126/"], diff --git a/profiling/tests/phpt/phpinfo_05.phpt b/profiling/tests/phpt/phpinfo_05.phpt index d3ec73c23fe..2ef73aa37d6 100644 --- a/profiling/tests/phpt/phpinfo_05.phpt +++ b/profiling/tests/phpt/phpinfo_05.phpt @@ -14,6 +14,8 @@ DD_PROFILING_ALLOCATION_ENABLED=no DD_PROFILING_EXPERIMENTAL_ALLOCATION_ENABLED=yes DD_PROFILING_EXCEPTION_ENABLED=no DD_PROFILING_EXPERIMENTAL_EXCEPTION_ENABLED=yes +DD_PROFILING_IO_ENABLED=no +DD_PROFILING_EXPERIMENTAL_IO_ENABLED=yes --INI-- assert.exception=1 opcache.jit=off @@ -43,6 +45,7 @@ $sections = [ ["Profiling Enabled", "true"], ["Allocation Profiling Enabled", "false"], ["Exception Profiling Enabled", "false"], + ["I/O Profiling Enabled", "false"], ]; foreach ($sections as [$key, $expected]) { diff --git a/profiling/tests/phpt/phpinfo_07.phpt b/profiling/tests/phpt/phpinfo_07.phpt index 526777e724b..863fac24866 100644 --- a/profiling/tests/phpt/phpinfo_07.phpt +++ b/profiling/tests/phpt/phpinfo_07.phpt @@ -16,6 +16,7 @@ DD_PROFILING_EXPERIMENTAL_CPU_TIME_ENABLED=no DD_PROFILING_ALLOCATION_ENABLED=no DD_PROFILING_EXCEPTION_ENABLED=no DD_PROFILING_TIMELINE_ENABLED=no +DD_PROFILING_EXPERIMENTAL_IO_ENABLED=no --INI-- assert.exception=1 opcache.jit=off @@ -48,7 +49,7 @@ $sections = [ ["Allocation Profiling Enabled", "false"], ["Exception Profiling Enabled", "false"], ["Timeline Enabled", "false"], - ["I/O Profiling Enabled", "true"], + ["I/O Profiling Enabled", "false"], ]; foreach ($sections as [$key, $expected]) { diff --git a/zend_abstract_interface/config/config.c b/zend_abstract_interface/config/config.c index 6fdabfe9079..93d7f567401 100644 --- a/zend_abstract_interface/config/config.c +++ b/zend_abstract_interface/config/config.c @@ -297,7 +297,9 @@ void zai_config_first_time_rinit(bool in_request) { for (uint16_t i = 0; i < zai_config_memoized_entries_count; i++) { zai_config_memoized_entry *memoized = &zai_config_memoized_entries[i]; - zai_config_find_and_set_value(memoized, i, in_request); + if (!in_request || memoized->ini_change != zai_config_minit_ini_change) { + zai_config_find_and_set_value(memoized, i, in_request); + } #if PHP_VERSION_ID >= 70300 zai_config_intern_zval(&memoized->decoded_value); #else @@ -331,3 +333,7 @@ bool zai_config_system_ini_change(zval *old_value, zval *new_value, zend_string (void)new_str; return false; } + +bool zai_config_minit_ini_change(zval *old_value, zval *new_value, zend_string *new_str) { + return zai_config_system_ini_change(old_value, new_value, new_str); +} diff --git a/zend_abstract_interface/config/config_ini.c b/zend_abstract_interface/config/config_ini.c index 85ae32eefb7..96139cd34ba 100644 --- a/zend_abstract_interface/config/config_ini.c +++ b/zend_abstract_interface/config/config_ini.c @@ -303,7 +303,8 @@ static void zai_config_add_ini_entry(zai_config_memoized_entry *memoized, zai_st entry->value = memoized->default_encoded_value.ptr; entry->value_length = memoized->default_encoded_value.len; entry->on_modify = ZaiConfigOnUpdateIni; - entry->modifiable = memoized->ini_change == zai_config_system_ini_change ? PHP_INI_SYSTEM : PHP_INI_ALL; + entry->modifiable = + memoized->ini_change == zai_config_system_ini_change || memoized->ini_change == zai_config_minit_ini_change ? PHP_INI_SYSTEM : PHP_INI_ALL; if (memoized->displayer) { entry->displayer = memoized->displayer; @@ -441,7 +442,7 @@ void zai_config_ini_rinit(void) { for (uint16_t i = 0; i < zai_config_memoized_entries_count; ++i) { ZAI_ENV_BUFFER_INIT(buf, ZAI_ENV_MAX_BUFSIZ); zai_config_memoized_entry *memoized = &zai_config_memoized_entries[i]; - if (memoized->ini_change == zai_config_system_ini_change) { + if (memoized->ini_change == zai_config_system_ini_change || memoized->ini_change == zai_config_minit_ini_change) { continue; } diff --git a/zend_abstract_interface/config/config_ini.h b/zend_abstract_interface/config/config_ini.h index d6224efa003..d59b27a2da4 100644 --- a/zend_abstract_interface/config/config_ini.h +++ b/zend_abstract_interface/config/config_ini.h @@ -38,6 +38,8 @@ typedef bool (*zai_config_apply_ini_change)(zval *old_value, zval *new_value, ze typedef bool (*zai_env_config_fallback)(zai_env_buffer *buf, bool pre_rinit); bool zai_config_system_ini_change(zval *old_value, zval *new_value, zend_string *new_str); +// A PHP_INI_SYSTEM value that cannot be refreshed from SAPI config after MINIT. +bool zai_config_minit_ini_change(zval *old_value, zval *new_value, zend_string *new_str); bool zai_config_is_modified(zai_config_id entry_id); void zai_config_change_default_ini(zai_config_id entry_id, zai_str str); diff --git a/zend_abstract_interface/config/tests/ini.cc b/zend_abstract_interface/config/tests/ini.cc index 5f44167645e..72a36de185c 100644 --- a/zend_abstract_interface/config/tests/ini.cc +++ b/zend_abstract_interface/config/tests/ini.cc @@ -16,6 +16,7 @@ typedef enum { EXT_CFG_INI_BAR_ALIASED_INT, EXT_CFG_INI_BAR_ALIASED_STRING, EXT_CFG_INI_BAZ_MAP_EMPTY, + EXT_CFG_INI_MINIT_BOOL, } ext_ini_cfg_id; static void ext_ini_env_to_ini_name(zai_str env_name, zai_config_name *ini_name) { @@ -35,6 +36,7 @@ static PHP_MINIT_FUNCTION(zai_config_ini) { EXT_CFG_ALIASED_ENTRY(INI_BAR_ALIASED_INT, INT, "0", aliases_int), EXT_CFG_ALIASED_ENTRY(INI_BAR_ALIASED_STRING, STRING, "0", aliases_string), EXT_CFG_ENTRY(INI_BAZ_MAP_EMPTY, MAP, ""), + ZAI_CONFIG_ENTRY(EXT_CFG_INI_MINIT_BOOL, INI_MINIT_BOOL, BOOL, "1", .ini_change = zai_config_minit_ini_change), }; if (!zai_config_minit(entries, (sizeof entries / sizeof entries[0]), ext_ini_env_to_ini_name, module_number)) { return FAILURE; @@ -551,6 +553,7 @@ static char *second_consumer_sapi_getenv(char *name, size_t name_len) { if (second_consumer_sapi_phase == 0) { if (strcmp(name, "INI_FOO_STRING") == 0) return estrdup("sapi_val"); if (strcmp(name, "INI_FOO_INT") == 0) return estrdup("2"); + if (strcmp(name, "INI_MINIT_BOOL") == 0) return estrdup("0"); } else if (second_consumer_sapi_phase == 1) { if (strcmp(name, "INI_FOO_INT") == 0) return estrdup("3"); } @@ -562,8 +565,8 @@ static char *second_consumer_sapi_getenv(char *name, size_t name_len) { // 1. SAPI is consulted on every rinit, including the first; sys env cache (set at minit) is the // fallback when SAPI returns NULL — consulting SAPI on first rinit is required for backwards // compatibility with health metrics -// 2. SAPI env takes priority over sys env for ALL entries, including those with original_on_modify — -// the presence of a second consumer does not affect SAPI precedence +// 2. SAPI env takes priority over sys env for regular entries, including those with +// original_on_modify; MINIT-only entries remain unchanged // 3. Sys env changes between requests are NOT reflected — the cache is immutable after minit (request 3) TEA_TEST_CASE_BARE("config/ini", "second consumer extension causes original_on_modify to be set", { REQUIRE(tea_sapi_sinit()); @@ -593,6 +596,10 @@ TEA_TEST_CASE_BARE("config/ini", "second consumer extension causes original_on_m REQUIRE(Z_TYPE_P(int_val) == IS_LONG); REQUIRE(Z_LVAL_P(int_val) == 2); // SAPI "2" overrides sys cache "1" + zval *minit_val = zai_config_get_value(EXT_CFG_INI_MINIT_BOOL); + REQUIRE(minit_val != NULL); + REQUIRE(Z_TYPE_P(minit_val) == IS_TRUE); // SAPI "0" cannot replace the MINIT value + REQUEST_END() // Change sys env between requests — cache is immutable after minit, this is ignored.