Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion profiling/src/allocation/allocation_ge84.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use crate::allocation::ALLOCATION_PROFILING_SIZE;
use crate::allocation::ALLOCATION_PROFILING_STATS;
use crate::bindings::{self as zend};
use crate::PROFILER_NAME;
use lazy_static::lazy_static;
use libc::{c_char, c_void, size_t};
use log::{debug, trace, warn};
use log::{debug, error, trace, warn};
use std::cell::UnsafeCell;
use std::ptr;
use std::sync::atomic::Ordering::SeqCst;
Expand Down Expand Up @@ -95,12 +96,26 @@ macro_rules! tls_zend_mm_state {
};
}

lazy_static! {
static ref JIT_ENABLED: bool = unsafe { zend::ddog_php_jit_enabled() };
}

pub fn first_rinit_should_disable_due_to_jit() -> bool {
if *JIT_ENABLED && zend::PHP_VERSION_ID >= 80400 {
error!("Memory allocation profiling will be disabled as long as JIT is active. To enable allocation profiling disable JIT. See https://github.com/DataDog/dd-trace-php/pull/3199");
true
} else {
false
}
}

/// This initializes the thread locale variable `ZEND_MM_STATE` with respect to the currently
/// installed `zend_mm_heap` in ZendMM. It guarantees compliance with the safety guarantees
/// described in the `ZendMMState` structure, specifically for `ZendMMState::alloc`,
/// `ZendMMState::realloc`, `ZendMMState::free`, `ZendMMState::gc` and `ZendMMState::shutdown`.
/// This function may panic if called out of order!
pub fn alloc_prof_ginit() {
unsafe { zend::ddog_php_opcache_init_handle() };
ZEND_MM_STATE.with(|cell| {
let zend_mm_state = cell.get();

Expand Down
2 changes: 1 addition & 1 deletion profiling/src/allocation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::cell::RefCell;
use std::sync::atomic::AtomicU64;

#[cfg(php_zend_mm_set_custom_handlers_ex)]
mod allocation_ge84;
pub mod allocation_ge84;
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
pub mod allocation_le83;

Expand Down
5 changes: 4 additions & 1 deletion profiling/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[cfg(not(php_zend_mm_set_custom_handlers_ex))]
use crate::allocation;
use crate::bindings::zai_config_type::*;
use crate::bindings::{
Expand Down Expand Up @@ -113,6 +112,10 @@ impl SystemSettings {
if allocation::allocation_le83::first_rinit_should_disable_due_to_jit() {
system_settings.profiling_allocation_enabled = false;
}
#[cfg(php_zend_mm_set_custom_handlers_ex)]
if allocation::allocation_ge84::first_rinit_should_disable_due_to_jit() {
system_settings.profiling_allocation_enabled = false;
}
swap(&mut system_settings, SYSTEM_SETTINGS.assume_init_mut());
}

Expand Down
7 changes: 6 additions & 1 deletion profiling/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,12 @@ unsafe extern "C" fn minfo(module_ptr: *mut zend::ModuleEntry) {
if system_settings.profiling_allocation_enabled {
yes
} else if zend::ddog_php_jit_enabled() {
b"Not available due to JIT being active, see https://github.com/DataDog/dd-trace-php/pull/2088 for more information.\0"
// Work around version-specific issues.
if cfg!(not(php_zend_mm_set_custom_handlers_ex)) {
b"Not available due to JIT being active, see https://github.com/DataDog/dd-trace-php/pull/2088 for more information.\0"
} else {
b"Not available due to JIT being active, see https://github.com/DataDog/dd-trace-php/pull/3199 for more information.\0"
}
} else if system_settings.profiling_enabled {
no
} else {
Expand Down
2 changes: 2 additions & 0 deletions profiling/tests/phpt/jit_01.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ if (PHP_VERSION_ID >= 80208 || PHP_VERSION_ID >= 80121 && PHP_VERSION_ID < 80200
echo "skip: PHP Version >= 8.1.21 and >= 8.2.8 have a fix for this";
if (PHP_VERSION_ID < 80000)
echo "skip: JIT requires PHP >= 8.0", PHP_EOL;
if (PHP_VERSION_ID >= 80300)
echo "skip: not affected version", PHP_EOL;
if (!extension_loaded('datadog-profiling'))
echo "skip: test requires datadog-profiling", PHP_EOL;
$arch = php_uname('m');
Expand Down
2 changes: 2 additions & 0 deletions profiling/tests/phpt/jit_02.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ if (PHP_VERSION_ID < 80120 || PHP_VERSION_ID >= 80200 && PHP_VERSION_ID < 80207)
echo "skip: unpatched PHP version, so JIT should be inactive";
if (PHP_VERSION_ID < 80000)
echo "skip: JIT requires PHP >= 8.0", PHP_EOL;
if (PHP_VERSION_ID >= 80300)
echo "skip: not affected version", PHP_EOL;
if (!extension_loaded('datadog-profiling'))
echo "skip: test requires datadog-profiling", PHP_EOL;
$arch = php_uname('m');
Expand Down
29 changes: 29 additions & 0 deletions profiling/tests/phpt/jit_03.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
[profiling] Allocation profiling should be disabled when JIT is active on PHP 8.4
--DESCRIPTION--
We did find a crash in PHP when collecting a stack sample in allocation
profiling when JIT is activated while a function becomes hot. For the time being
we make sure to disable allocation profiling when we detect the JIT is enabled.
--SKIPIF--
<?php
if (PHP_VERSION_ID < 80400)
echo "skip: PHP Version < 8.4 are not affected", PHP_EOL;
if (!extension_loaded('datadog-profiling'))
echo "skip: test requires datadog-profiling", PHP_EOL;
?>
--INI--
datadog.profiling.enabled=yes
datadog.profiling.log_level=debug
datadog.profiling.allocation_enabled=yes
datadog.profiling.experimental_cpu_time_enabled=no
zend_extension=opcache
opcache.enable_cli=1
opcache.jit=tracing
opcache.jit_buffer_size=4M
--FILE--
<?php
echo "Done.", PHP_EOL;
?>
--EXPECTF--
%aMemory allocation profiling will be disabled as long as JIT is active. To enable allocation profiling disable JIT. See https://github.com/DataDog/dd-trace-php/pull/3199
%ADone.%a
2 changes: 1 addition & 1 deletion profiling/tests/phpt/phpinfo_04.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The profiler's phpinfo section contains important debugging information. This
test verifies that certain information is present.
--SKIPIF--
<?php
if (PHP_VERSION_ID < 80120 || PHP_VERSION_ID >= 80200 && PHP_VERSION_ID < 80207)
if (PHP_VERSION_ID < 80120 || PHP_VERSION_ID >= 80200 && PHP_VERSION_ID < 80207 || PHP_VERSION_ID >= 80400)
echo "skip: unpatched PHP version, so JIT should be inactive";
if (PHP_VERSION_ID < 80000)
echo "skip: JIT requires PHP >= 8.0", PHP_EOL;
Expand Down
Loading