Skip to content

Commit 33d7046

Browse files
committed
Merge branch 'master' of github.com:DataDog/dd-trace-php into bob/log
2 parents 5ccc6f7 + 679da8e commit 33d7046

File tree

20 files changed

+694
-485
lines changed

20 files changed

+694
-485
lines changed

.circleci/continue_config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,7 @@ jobs:
19041904
DD_TRACE_AGENT_PORT: 80
19051905
DD_TRACE_AGENT_FLUSH_INTERVAL: 1000
19061906
INSTALL_TYPE: << parameters.install_type >>
1907+
RUST_BACKTRACE: 1
19071908
- <<: *IMAGE_DOCKER_REQUEST_REPLAYER
19081909
steps:
19091910
- restore_cache:
@@ -1975,6 +1976,7 @@ jobs:
19751976
VERIFY_APACHE: << parameters.verify_apache >>
19761977
INSTALL_MODE: << parameters.install_mode >>
19771978
INSTALL_TYPE: << parameters.install_type >>
1979+
RUST_BACKTRACE: 1
19781980
- <<: *IMAGE_DOCKER_REQUEST_REPLAYER
19791981
steps:
19801982
- restore_cache:
@@ -2057,6 +2059,8 @@ jobs:
20572059
- run:
20582060
name: Run tests
20592061
command: make -C dockerfiles/verify_packages test_installer
2062+
environment:
2063+
RUST_BACKTRACE: 1
20602064

20612065
randomized_tests:
20622066
working_directory: ~/datadog

.github/workflows/prof_asan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ jobs:
6060
switch-php nts-asan
6161
cd profiling/tests
6262
cp -v $(php-config --prefix)/lib/php/build/run-tests.php .
63-
php run-tests.php --asan -d extension=datadog-profiling.so phpt
63+
php run-tests.php --show-diff --asan -d extension=datadog-profiling.so phpt
6464

appsec/src/extension/logging.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,12 @@ static void _mlog_file(dd_log_level_t level, const char *format, va_list args,
377377
_dd_log_level_to_str(level), message_data, file, line, function);
378378

379379
efree(message_data);
380-
TSRM_MUTEX_LOCK(_mutex);
381-
ssize_t written = write(_mlog_fd, data, data_len);
382-
TSRM_MUTEX_UNLOCK(_mutex);
380+
ssize_t written;
381+
do {
382+
TSRM_MUTEX_LOCK(_mutex);
383+
written = write(_mlog_fd, data, data_len);
384+
TSRM_MUTEX_UNLOCK(_mutex);
385+
} while (written == -1 && errno == EINTR);
383386
efree(data);
384387

385388
if (written == -1) {
@@ -451,13 +454,23 @@ void dd_log_shutdown()
451454
{
452455
mlog(dd_log_debug, "Shutting down the file logging");
453456

454-
#ifdef ZTS
455-
tsrm_mutex_free(_mutex);
456-
_mutex = NULL;
457-
#endif
458-
if (_log_strategy == log_use_file && _mlog_fd != -1 &&
459-
_mlog_fd > fileno(stderr)) {
460-
int ret = close(_mlog_fd);
457+
if (_log_strategy == log_use_file &&
458+
atomic_load_explicit(&_initialized, memory_order_acquire) &&
459+
_mlog_fd != -1 && _mlog_fd > fileno(stderr)) {
460+
// no need for the mutex at this point
461+
// all the zts workers should have been done
462+
// we're guaranteed visibility of the write to _mlog_fd by _initialized
463+
int ret;
464+
ret = fsync(_mlog_fd);
465+
if (ret == -1) {
466+
_mlog_php_varargs(dd_log_warning,
467+
"Error fsyncing the log file (errno %d: %s)", errno,
468+
_strerror(errno));
469+
}
470+
do {
471+
ret = close(_mlog_fd);
472+
} while (ret == -1 && errno == EINTR);
473+
461474
if (ret == -1) {
462475
_mlog_php_varargs(dd_log_warning,
463476
"Error closing the log file (errno %d: %s)", errno,
@@ -467,6 +480,11 @@ void dd_log_shutdown()
467480
closelog();
468481
}
469482

483+
#ifdef ZTS
484+
tsrm_mutex_free(_mutex);
485+
_mutex = NULL;
486+
#endif
487+
470488
_mlog_fd = -1;
471489
_log_strategy = log_use_nothing;
472490
atomic_store(&_initialized, false);

appsec/src/extension/request_abort.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ static bool _abort_prelude()
409409
mlog_g(dd_log_warning, "Failed clearing current headers");
410410
}
411411

412-
mlog_g(dd_log_debug, "Discarding output buffers");
413412
php_output_discard_all();
413+
mlog_g(dd_log_debug, "Output buffers have been discarded");
414414
return true;
415415
}
416416

profiling/src/allocation.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,25 @@ lazy_static! {
109109
static ref JIT_ENABLED: bool = unsafe { zend::ddog_php_jit_enabled() };
110110
}
111111

112+
pub fn first_rinit_should_disable_due_to_jit() -> bool {
113+
if NEEDS_RUN_TIME_CHECK_FOR_ENABLED_JIT
114+
&& allocation_profiling_needs_disabled_for_jit(unsafe { crate::PHP_VERSION_ID })
115+
&& *JIT_ENABLED
116+
{
117+
error!("Memory allocation profiling will be disabled as long as JIT is active. To enable allocation profiling disable JIT or upgrade PHP to at least version 8.1.21 or 8.2.8. See https://github.com/DataDog/dd-trace-php/pull/2088");
118+
true
119+
} else {
120+
false
121+
}
122+
}
123+
112124
pub fn allocation_profiling_rinit() {
113125
let allocation_profiling: bool = REQUEST_LOCALS.with(|cell| {
114126
match cell.try_borrow() {
115-
Ok(locals) => locals.profiling_allocation_enabled,
127+
Ok(locals) => {
128+
let system_settings = locals.system_settings();
129+
system_settings.profiling_allocation_enabled
130+
},
116131
Err(_err) => {
117132
error!("Memory allocation was not initialized correctly due to a borrow error. Please report this to Datadog.");
118133
false
@@ -124,18 +139,6 @@ pub fn allocation_profiling_rinit() {
124139
return;
125140
}
126141

127-
if NEEDS_RUN_TIME_CHECK_FOR_ENABLED_JIT
128-
&& allocation_profiling_needs_disabled_for_jit(unsafe { crate::PHP_VERSION_ID })
129-
&& *JIT_ENABLED
130-
{
131-
error!("Memory allocation profiling will be disabled as long as JIT is active. To enable allocation profiling disable JIT or upgrade PHP to at least version 8.1.21 or 8.2.8. See https://github.com/DataDog/dd-trace-php/pull/2088");
132-
REQUEST_LOCALS.with(|cell| {
133-
let mut locals = cell.borrow_mut();
134-
locals.profiling_allocation_enabled = false;
135-
});
136-
return;
137-
}
138-
139142
unsafe {
140143
HEAP = Some(zend::zend_mm_get_heap());
141144
}
@@ -180,11 +183,9 @@ pub fn allocation_profiling_rinit() {
180183

181184
// `is_zend_mm()` should be `false` now, as we installed our custom handlers
182185
if is_zend_mm() {
183-
error!("Memory allocation profiling could not be enabled. Please feel free to fill an issue stating the PHP version and installed modules. Most likely the reason is your PHP binary was compiled with `ZEND_MM_CUSTOM` being disabled.");
184-
REQUEST_LOCALS.with(|cell| {
185-
let mut locals = cell.borrow_mut();
186-
locals.profiling_allocation_enabled = false;
187-
});
186+
// Can't proceed with it being disabled, because that's a system-wide
187+
// setting, not per-request.
188+
panic!("Memory allocation profiling could not be enabled. Please feel free to fill an issue stating the PHP version and installed modules. Most likely the reason is your PHP binary was compiled with `ZEND_MM_CUSTOM` being disabled.");
188189
} else {
189190
trace!("Memory allocation profiling enabled.")
190191
}
@@ -193,7 +194,7 @@ pub fn allocation_profiling_rinit() {
193194
pub fn allocation_profiling_rshutdown() {
194195
let allocation_profiling = REQUEST_LOCALS.with(|cell| {
195196
cell.try_borrow()
196-
.map(|locals| locals.profiling_allocation_enabled)
197+
.map(|locals| locals.system_settings().profiling_allocation_enabled)
197198
.unwrap_or(false)
198199
});
199200

@@ -310,7 +311,7 @@ unsafe extern "C" fn alloc_profiling_gc_mem_caches(
310311
) {
311312
let allocation_profiling: bool = REQUEST_LOCALS.with(|cell| {
312313
cell.try_borrow()
313-
.map(|locals| locals.profiling_allocation_enabled)
314+
.map(|locals| locals.system_settings().profiling_allocation_enabled)
314315
// Not logging here to avoid potentially overwhelming logs.
315316
.unwrap_or(false)
316317
});

profiling/src/bindings/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ extern "C" {
302302
/// (single byte of null, len of 0).
303303
pub fn zai_str_from_zstr(zstr: Option<&mut zend_string>) -> zai_str;
304304

305+
/// Returns the configuration item for the given config id. Note that the
306+
/// lifetime is roughly static, but technically it is from first rinit
307+
/// until mshutdown.
308+
pub(crate) fn ddog_php_prof_get_memoized_config(config_id: ConfigId) -> *mut zval;
309+
305310
/// Registers the run_time_cache slot with the engine. Must be done in
306311
/// module init or extension startup.
307312
pub fn ddog_php_prof_function_run_time_cache_init(module_name: *const c_char);
@@ -332,6 +337,7 @@ extern "C" {
332337
pub fn ddog_php_prof_is_post_startup() -> bool;
333338
}
334339

340+
use crate::config::ConfigId;
335341
pub use zend_module_dep as ModuleDep;
336342

337343
impl ModuleDep {
@@ -468,15 +474,25 @@ impl TryFrom<&mut zval> for String {
468474
type Error = StringError;
469475

470476
fn try_from(zval: &mut zval) -> Result<Self, Self::Error> {
477+
Cow::try_from(zval).map(Cow::into_owned)
478+
}
479+
}
480+
481+
impl<'a> TryFrom<&'a mut zval> for Cow<'a, str> {
482+
type Error = StringError;
483+
484+
fn try_from(zval: &'a mut zval) -> Result<Self, Self::Error> {
471485
let r#type = unsafe { zval.u1.v.type_ };
472486
if r#type == IS_STRING {
473487
// This shouldn't happen, very bad, something screwed up.
474488
if unsafe { zval.value.str_.is_null() } {
475489
return Err(StringError::Null);
476490
}
491+
// SAFETY: checked the pointer wasn't null above.
492+
let reference: Option<&'a mut zend_string> = unsafe { zval.value.str_.as_mut() };
477493

478-
// Safety: checked the pointer wasn't null above.
479-
let str = unsafe { zai_str_from_zstr(zval.value.str_.as_mut()) }.into_string();
494+
// SAFETY: calling extern "C" with correct params.
495+
let str = unsafe { zai_str_from_zstr(reference) }.into_string_lossy();
480496
Ok(str)
481497
} else {
482498
Err(StringError::Type(r#type))
@@ -573,6 +589,12 @@ impl<'a> ZaiStr<'a> {
573589
pub fn to_string_lossy(&self) -> Cow<str> {
574590
String::from_utf8_lossy(self.as_bytes())
575591
}
592+
593+
#[inline]
594+
pub fn into_string_lossy(self) -> Cow<'a, str> {
595+
let bytes = self.as_bytes();
596+
String::from_utf8_lossy(bytes)
597+
}
576598
}
577599

578600
#[repr(C)]

profiling/src/capi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extern "C" fn ddog_php_prof_trigger_time_sample() {
4141
use std::sync::atomic::Ordering;
4242
super::REQUEST_LOCALS.with(|cell| {
4343
if let Ok(locals) = cell.try_borrow() {
44-
if locals.profiling_enabled {
44+
if locals.system_settings().profiling_enabled {
4545
// Safety: only vm interrupts are stored there, or possibly null (edges only).
4646
if let Some(vm_interrupt) = unsafe { locals.vm_interrupt_addr.as_ref() } {
4747
locals.interrupt_count.fetch_add(1, Ordering::SeqCst);

0 commit comments

Comments
 (0)