From a73871dea2b724430d1b7db1e90e4a0eee8dbf6f Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Thu, 30 Jul 2026 16:57:36 +0200 Subject: [PATCH 1/3] fix(profiling): support PHP 8.6 --- profiling/build.rs | 4 ++-- profiling/src/bindings/mod.rs | 2 +- profiling/src/config.rs | 2 +- profiling/src/php_ffi.c | 6 ++++-- profiling/src/php_ffi.h | 2 ++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/profiling/build.rs b/profiling/build.rs index 140662e6997..c14c4bc9bd4 100644 --- a/profiling/build.rs +++ b/profiling/build.rs @@ -176,8 +176,8 @@ fn build_zend_php_ffis( .chain([Path::new("../zend_abstract_interface")]) .chain([Path::new("../")]), ) - .flag_if_supported("-std=c11") - .flag_if_supported("-std=c17"); + .flag_if_supported("-std=gnu11") + .flag_if_supported("-std=gnu17"); #[cfg(feature = "test")] build.define("CFG_TEST", "1"); build.compile("php_ffi"); diff --git a/profiling/src/bindings/mod.rs b/profiling/src/bindings/mod.rs index 220be2cd123..13315aef197 100644 --- a/profiling/src/bindings/mod.rs +++ b/profiling/src/bindings/mod.rs @@ -162,7 +162,7 @@ impl _zend_function { #[inline] pub fn is_internal(&self) -> bool { // SAFETY: the function's type field is always safe to access. - unsafe { self.type_ == ZEND_INTERNAL_FUNCTION } + unsafe { self.type_ == 1 } // ZEND_INTERNAL_FUNCTION } /// Returns the op_array if this is a user function or eval code. diff --git a/profiling/src/config.rs b/profiling/src/config.rs index b50fb04a953..dd968304f1b 100644 --- a/profiling/src/config.rs +++ b/profiling/src/config.rs @@ -917,7 +917,7 @@ unsafe extern "C" fn parse_profiling_enabled( /// Display the profiling enabled config value unsafe extern "C" fn display_profiling_enabled(ini_entry: *mut zend_ini_entry, type_: c_int) { let tmp_value: *mut zend_string = - if type_ as u32 == ZEND_INI_DISPLAY_ORIG && (*ini_entry).modified != 0 { + if type_ as u32 == ZEND_INI_DISPLAY_ORIG && (*ini_entry).modified as u8 != 0 { if !(*ini_entry).orig_value.is_null() { (*ini_entry).orig_value } else { diff --git a/profiling/src/php_ffi.c b/profiling/src/php_ffi.c index 1e906f3cbd3..9a82c509c6f 100644 --- a/profiling/src/php_ffi.c +++ b/profiling/src/php_ffi.c @@ -654,7 +654,7 @@ bool ddog_php_jit_enabled() { } // Check opcache.jit_buffer_size, no buffer -> no JIT - char *buffer_size_str = zend_ini_string("opcache.jit_buffer_size", sizeof("opcache.jit_buffer_size") - 1, 0); + const char *buffer_size_str = zend_ini_string("opcache.jit_buffer_size", sizeof("opcache.jit_buffer_size") - 1, 0); if (!buffer_size_str || strlen(buffer_size_str) == 0 || strcmp(buffer_size_str, "0") == 0) { return false; } @@ -666,7 +666,7 @@ bool ddog_php_jit_enabled() { } // Finally check the opcache.jit setting - char *jit_str = zend_ini_string("opcache.jit", sizeof("opcache.jit") - 1, 0); + const char *jit_str = zend_ini_string("opcache.jit", sizeof("opcache.jit") - 1, 0); if (!jit_str || strlen(jit_str) == 0 || strcmp(jit_str, "disable") == 0 || strcmp(jit_str, "off") == 0 || @@ -685,6 +685,8 @@ bool ddog_php_jit_enabled() { #if PHP_VERSION_ID < 70200 #define zend_parse_parameters_none_throw() \ (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : zend_parse_parameters_throw(ZEND_NUM_ARGS(), "")) +#elif PHP_VERSION_ID >= 80600 +#define zend_parse_parameters_none_throw() zend_parse_parameters_none() #endif #if CFG_TRIGGER_TIME_SAMPLE diff --git a/profiling/src/php_ffi.h b/profiling/src/php_ffi.h index 558c3de4413..4d4f3cfe839 100644 --- a/profiling/src/php_ffi.h +++ b/profiling/src/php_ffi.h @@ -38,10 +38,12 @@ // Used to communicate strings from C -> Rust. #include +#if PHP_VERSION_ID < 80600 /* C11 allows a duplicate typedef provided they are the same, so this should be * fine as long as we compile with C11 or higher. */ typedef ZEND_RESULT_CODE zend_result; +#endif /** * Returns macro expansion of ZEND_EXTENSION_BUILD_ID, which bindgen cannot From d120f76563156f14802480a0e5c53ea8e35261c9 Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Thu, 30 Jul 2026 17:19:20 +0200 Subject: [PATCH 2/3] fix(profiling): allow version-dependent ini cast --- profiling/src/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/profiling/src/config.rs b/profiling/src/config.rs index dd968304f1b..6485554d278 100644 --- a/profiling/src/config.rs +++ b/profiling/src/config.rs @@ -916,6 +916,8 @@ unsafe extern "C" fn parse_profiling_enabled( /// Display the profiling enabled config value unsafe extern "C" fn display_profiling_enabled(ini_entry: *mut zend_ini_entry, type_: c_int) { + // PHP 8.6 changed this field from u8 to bool, so the cast is redundant only on older PHP. + #[allow(clippy::unnecessary_cast)] let tmp_value: *mut zend_string = if type_ as u32 == ZEND_INI_DISPLAY_ORIG && (*ini_entry).modified as u8 != 0 { if !(*ini_entry).orig_value.is_null() { From d0a81c33f6ee560bd368bbebff36cb94ec7f2c31 Mon Sep 17 00:00:00 2001 From: Florian Engelhardt Date: Thu, 30 Jul 2026 17:36:36 +0200 Subject: [PATCH 3/3] found `ZEND_INTERNAL_FUNCTION` in another header file --- profiling/src/bindings/mod.rs | 2 +- profiling/src/php_ffi.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/profiling/src/bindings/mod.rs b/profiling/src/bindings/mod.rs index 13315aef197..220be2cd123 100644 --- a/profiling/src/bindings/mod.rs +++ b/profiling/src/bindings/mod.rs @@ -162,7 +162,7 @@ impl _zend_function { #[inline] pub fn is_internal(&self) -> bool { // SAFETY: the function's type field is always safe to access. - unsafe { self.type_ == 1 } // ZEND_INTERNAL_FUNCTION + unsafe { self.type_ == ZEND_INTERNAL_FUNCTION } } /// Returns the op_array if this is a user function or eval code. diff --git a/profiling/src/php_ffi.h b/profiling/src/php_ffi.h index 4d4f3cfe839..51a36b08590 100644 --- a/profiling/src/php_ffi.h +++ b/profiling/src/php_ffi.h @@ -1,4 +1,7 @@ #include +#if PHP_VERSION_ID >= 80600 +#include +#endif #include #include #include