From 8a9092703d02543978274ac97e5cb83f065b8805 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 11 May 2026 20:16:54 +0200 Subject: [PATCH 01/25] Add support for macos test_c run --- .gitlab/generate-tracer.php | 37 +++++++++++++++++++ .gitlab/macos.yml | 0 Makefile | 2 +- libdatadog | 2 +- .../background_sender_ipv6_support.phpt | 1 + tests/ext/read_c_configuration.phpt | 3 -- tests/ext/startup_logging_diagnostics.phpt | 3 +- tests/ext/telemetry/composer.phpt | 36 +++++++++--------- tests/ext/telemetry/config.phpt | 31 +++++++++++++--- 9 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 .gitlab/macos.yml diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 5e7488158ec..a1abd8cd64b 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -197,6 +197,43 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { ]); ?> +"macos test_c": + stage: test + tags: ["macos:sonoma-arm64"] + timeout: 30m + variables: + PHP_MACOS_VERSION: "8.5.7" + PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" + before_script: + - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium + - mkdir -p /tmp/php-build + - curl -fL "https://github.com/php/php-src/archive/refs/tags/php-${PHP_MACOS_VERSION}.tar.gz" | tar xz -C /tmp/php-build + - cd "/tmp/php-build/php-src-php-${PHP_MACOS_VERSION}" + - ./buildconf --force + - | + export PATH="$(brew --prefix bison)/bin:$(brew --prefix libxml2)/bin:${PATH}" + export PKG_CONFIG_PATH="$(brew --prefix libxml2)/lib/pkgconfig:${PKG_CONFIG_PATH:-}" + export LDFLAGS="-L$(brew --prefix libxml2)/lib ${LDFLAGS:-}" + export CPPFLAGS="-I$(brew --prefix libxml2)/include ${CPPFLAGS:-}" + ./configure \ + --prefix="${PHP_INSTALL_DIR}" \ + --enable-debug \ + --enable-zts \ + --without-iconv \ + --with-openssl="$(brew --prefix openssl)" \ + --with-libxml \ + --enable-mbstring \ + --with-sodium + - make -j"$(sysctl -n hw.ncpu)" + - make install + - cd "${CI_PROJECT_DIR}" + - rustup update stable && rustup default stable + script: + - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" + - php --version + - make -j"$(sysctl -n hw.ncpu)" + - make test_c + "Prepare code": stage: compile diff --git a/.gitlab/macos.yml b/.gitlab/macos.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Makefile b/Makefile index ec877d56f95..9ea12bdeb5b 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ TRACER_SOURCES_INI := -d datadog.trace.sources_path=$(TRACER_SOURCE_DIR) RUN_TESTS_IS_PARALLEL ?= $(shell test $(PHP_MAJOR_MINOR) -ge 74 && echo 1) # shuffle parallel tests to evenly distribute test load, avoiding a batch of 32 tests being request-replayer tests -RUN_TESTS_CMD := DD_SERVICE= DD_ENV= REPORT_EXIT_STATUS=1 TEST_PHP_SRCDIR=$(PROJECT_ROOT) USE_TRACKED_ALLOC=1 php -n -d 'memory_limit=-1' $(BUILD_DIR)/run-tests.php $(if $(QUIET_TESTS),,-g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP) $(if $(ASAN), --asan) --show-diff -n -p $(shell which php) -q $(if $(RUN_TESTS_IS_PARALLEL), --shuffle -j$(MAX_TEST_PARALLELISM)) +RUN_TESTS_CMD := DD_SERVICE= DD_ENV= REPORT_EXIT_STATUS=1 TEST_PHP_SRCDIR=$(PROJECT_ROOT) USE_TRACKED_ALLOC=1 php -n -d 'memory_limit=-1' $(BUILD_DIR)/run-tests.php $(if $(QUIET_TESTS),,-g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP) $(if $(ASAN), --asan) --show-diff -n -p $(shell which php) -q $(if $(RUN_TESTS_IS_PARALLEL), --shuffle -j$(MAX_TEST_PARALLELISM)) -d datadog.agent_host=127.0.0.1 -d datadog.trace.agent_port=1 C_FILES = $(shell find components components-rs ext src/dogstatsd tracer zend_abstract_interface -name '*.c' -o -name '*.h' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) TEST_FILES = $(shell find tests/ext -name '*.php*' -o -name '*.inc' -o -name '*.json' -o -name '*.yaml' -o -name 'CONFLICTS' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) diff --git a/libdatadog b/libdatadog index b3813948bfe..902002a1adb 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit b3813948bfe1c12223a5dbcafe10cff83857780e +Subproject commit 902002a1adb24bc11b10b093a3053a106663f1dd diff --git a/tests/ext/background-sender/background_sender_ipv6_support.phpt b/tests/ext/background-sender/background_sender_ipv6_support.phpt index df66ad29d2f..497cae1f428 100644 --- a/tests/ext/background-sender/background_sender_ipv6_support.phpt +++ b/tests/ext/background-sender/background_sender_ipv6_support.phpt @@ -8,6 +8,7 @@ include_once __DIR__ . '/../startup_logging.inc'; $logs = dd_get_startup_logs([], [ 'DD_AGENT_HOST' => '::1', + 'DD_TRACE_AGENT_PORT' => '8126', 'DD_TRACE_DEBUG' => 1, 'DD_TRACE_AGENT_TIMEOUT' => 200, 'DD_TRACE_RETRY_INTERVAL' => 1, diff --git a/tests/ext/read_c_configuration.phpt b/tests/ext/read_c_configuration.phpt index 575a961b30e..01c77b3e191 100644 --- a/tests/ext/read_c_configuration.phpt +++ b/tests/ext/read_c_configuration.phpt @@ -7,8 +7,6 @@ DD_TRACE_MEMORY_LIMIT=9999 --EXPECT-- some_known_host -8126 FALSE FALSE 9999 diff --git a/tests/ext/startup_logging_diagnostics.phpt b/tests/ext/startup_logging_diagnostics.phpt index d278990e7c9..865e712df7d 100644 --- a/tests/ext/startup_logging_diagnostics.phpt +++ b/tests/ext/startup_logging_diagnostics.phpt @@ -14,6 +14,7 @@ $env = [ 'DD_TRACE_AGENT_TIMEOUT' => 200, 'DD_TRACE_RETRY_INTERVAL' => 1, 'DD_AGENT_HOST' => 'invalid_host', + 'DD_TRACE_AGENT_PORT' => '2', 'DD_SERVICE' => 'foo_service', 'DD_TAGS' => 'foo:tag', ]; @@ -33,7 +34,7 @@ var_dump(strncasecmp(PHP_OS, "WIN", 3) == 0 || isset($logs["agent_error"])); --EXPECTF-- open_basedir_sources_allowed: false service: "foo_service" -agent_url: "http://invalid_host:8126" +agent_url: "http://invalid_host:2" tags: {"foo":"tag"} d%s.sources_path: "%s/includes/" open_basedir_configured: true diff --git a/tests/ext/telemetry/composer.phpt b/tests/ext/telemetry/composer.phpt index 15b27be5b12..75e58b670ce 100644 --- a/tests/ext/telemetry/composer.phpt +++ b/tests/ext/telemetry/composer.phpt @@ -24,6 +24,7 @@ include __DIR__ . '/vendor/autoload.php'; DDTrace\close_span(); dd_trace_internal_fn("finalize_telemetry"); +$initial_deps = []; for ($i = 0; $i < 300; ++$i) { ("us" . "leep")(100000); @@ -33,8 +34,11 @@ for ($i = 0; $i < 300; ++$i) { $json = json_decode($l, true); $batch = $json["request_type"] == "message-batch" ? $json["payload"] : [$json]; foreach ($batch as $json) { + if ($json["request_type"] == "app-started") { + $initial_deps = $json["payload"]["dependencies"] ?? []; + } if ($json["request_type"] == "app-dependencies-loaded") { - print_r($json["payload"]); + print_r(array_merge($initial_deps, $json["payload"]["dependencies"])); break 3; } } @@ -51,26 +55,22 @@ if ($i == 300) { Included Array ( - [dependencies] => Array + [0] => Array ( - [0] => Array - ( - [name] => datadog/dd-trace - [version] => dev-master - [hash] => - [metadata] => - ) - - [1] => Array - ( - [name] => ext-Core - [version] => %s - [hash] => - [metadata] => - ) -%a + [name] => datadog/dd-trace + [version] => dev-master + [hash] => + [metadata] => ) + [1] => Array + ( + [name] => ext-Core + [version] => %s + [hash] => + [metadata] => + ) +%a ) --CLEAN-- Array + ( + [name] => DD_AGENT_HOST + [value] => 127.0.0.2 + [origin] => env_var + [config_id] => + [seq_id] => + ) + + [2] => Array + ( + [name] => DD_TRACE_AGENT_PORT + [value] => 3 + [origin] => env_var + [config_id] => + [seq_id] => + ) + + [3] => Array ( [name] => DD_INSTRUMENTATION_TELEMETRY_ENABLED [value] => 1 @@ -92,7 +111,7 @@ Array [seq_id] => ) - [2] => Array + [4] => Array ( [name] => DD_TRACE_GIT_METADATA_ENABLED [value] => 0 @@ -101,7 +120,7 @@ Array [seq_id] => ) - [3] => Array + [5] => Array ( [name] => DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED [value] => 0 @@ -110,7 +129,7 @@ Array [seq_id] => ) - [4] => Array + [6] => Array ( [name] => DD_TRACE_IGNORE_AGENT_SAMPLING_RATES [value] => 1 @@ -119,7 +138,7 @@ Array [seq_id] => ) - [5] => Array + [7] => Array ( [name] => DD_TRACE_GENERATE_ROOT_SPAN [value] => 0 @@ -128,7 +147,7 @@ Array [seq_id] => ) - [6] => Array + [8] => Array ( [name] => ssi_forced_injection_enabled [value] => False From b3278c7de93a32ad7d2f8b8310e8bbedcab59180 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 13 May 2026 18:03:47 +0200 Subject: [PATCH 02/25] Handle MacOS EMSGSIZE Signed-off-by: Bob Weinand --- .gitlab/generate-tracer.php | 14 +++++++++++++- ext/signals.c | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index a1abd8cd64b..9fb226ae255 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -204,9 +204,11 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { variables: PHP_MACOS_VERSION: "8.5.7" PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" + _DD_DEBUG_SIDECAR_LOG_LEVEL: trace + _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log" before_script: - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium - - mkdir -p /tmp/php-build + - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" - curl -fL "https://github.com/php/php-src/archive/refs/tags/php-${PHP_MACOS_VERSION}.tar.gz" | tar xz -C /tmp/php-build - cd "/tmp/php-build/php-src-php-${PHP_MACOS_VERSION}" - ./buildconf --force @@ -230,9 +232,19 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - rustup update stable && rustup default stable script: - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" + - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" - php --version - make -j"$(sysctl -n hw.ncpu)" - make test_c + after_script: + - mkdir -p "${CI_PROJECT_DIR}/artifacts/diffs" + - find . -type f \( -name '*.diff' -o -name '*.mem' \) -not -path '*/vendor/*' -exec cp '{}' "${CI_PROJECT_DIR}/artifacts/diffs/" \; || true + artifacts: + when: always + reports: + junit: "artifacts/tests/php-tests.xml" + paths: + - "artifacts/" "Prepare code": diff --git a/ext/signals.c b/ext/signals.c index f883727dadc..f9eb2b9c8f5 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -150,8 +150,8 @@ static zend_always_inline zend_string *dd_crasht_find_ini_by_tag(ddog_CharSlice // On PHP 8.0+ these INI should all exist, but guard against the NULL case // in case something goes wrong, or this changes in a future version. if (UNEXPECTED(!value)) { - LOG(WARN, - "crashtracker setup failed to find INI \"%.*s\"--is it removed in a newer version?", + LOG(DEBUG, + "crashtracker setup: INI \"%.*s\" not found (maybe compiled out in this PHP build)", (int) ini.len, ini.ptr); } return value; From 7ac0c5a6a663e597e8605e470e1011a29ec5eac7 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 15 May 2026 22:51:22 +0200 Subject: [PATCH 03/25] codesign ddtrace.so after build on macOS macOS invalidates the code signature when the .so is modified, causing SIGKILL (exit 137) when PHP processes try to load it. Re-sign with an ad-hoc signature after each build. Co-Authored-By: Claude Sonnet 4.6 --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 9ea12bdeb5b..7b42ef09a8b 100644 --- a/Makefile +++ b/Makefile @@ -137,6 +137,7 @@ $(BUILD_DIR)/Makefile: $(BUILD_DIR)/configure $(BUILD_DIR)/.rust_files_list $(SO_FILE): $(if $(ASSUME_COMPILED),, $(ALL_OBJECT_FILES) $(BUILD_DIR)/compile_rust.sh) $(if $(ASSUME_COMPILED),,$(Q) $(MAKE) -C $(BUILD_DIR) -j) + $(if $(filter Darwin,$(shell uname -s)),$(Q) codesign --force --sign - $@,) $(AR_FILE): $(ALL_OBJECT_FILES) $(Q) $(MAKE) -C $(BUILD_DIR) -j ./modules/ddtrace.a all From c2b47e715a9a6ce6f07573d175c3090f388f46cb Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 19 Jun 2026 17:18:07 +0200 Subject: [PATCH 04/25] Run with timeout for artifacts Signed-off-by: Bob Weinand --- .gitlab/generate-tracer.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 9fb226ae255..cde1f8ed01d 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -200,7 +200,6 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { "macos test_c": stage: test tags: ["macos:sonoma-arm64"] - timeout: 30m variables: PHP_MACOS_VERSION: "8.5.7" PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" @@ -235,7 +234,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" - php --version - make -j"$(sysctl -n hw.ncpu)" - - make test_c + - timeout 20m make test_c after_script: - mkdir -p "${CI_PROJECT_DIR}/artifacts/diffs" - find . -type f \( -name '*.diff' -o -name '*.mem' \) -not -path '*/vendor/*' -exec cp '{}' "${CI_PROJECT_DIR}/artifacts/diffs/" \; || true From b0a16503fdd5175228050987dd34a374df43dea2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 4 Sep 2026 21:58:18 +0200 Subject: [PATCH 05/25] fix: update datadog-live-debugger references after libdatadog rename The libdatadog submodule bump crosses de67b226e (renamed datadog-live-debugger -> libdd-live-debugger for publishing), so the old crate name/path no longer resolves. Co-Authored-By: Claude Sonnet 5 --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- cbindgen.toml | 4 ++-- components-rs/remote_config.rs | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2ec5c0abf2..a102d1172d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3018,7 +3018,7 @@ dependencies = [ [[package]] name = "libdd-data-pipeline-core" -version = "1.0.0" +version = "0.1.0" dependencies = [ "bytes", "futures", @@ -3185,7 +3185,7 @@ dependencies = [ [[package]] name = "libdd-live-debugger" -version = "1.0.0" +version = "0.1.0" dependencies = [ "anyhow", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 535898d16f8..fc8f7e3f9f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,8 +51,8 @@ libdd-common = { path = "libdatadog/libdd-common", features = ["cgroup_testing"] libdd-common-ffi = { path = "libdatadog/libdd-common-ffi", default-features = false } libdd-telemetry = { path = "libdatadog/libdd-telemetry" } libdd-telemetry-ffi = { path = "libdatadog/libdd-telemetry-ffi", default-features = false } -datadog-live-debugger = { package = "libdd-live-debugger", path = "libdatadog/libdd-live-debugger" } -datadog-live-debugger-ffi = { package = "libdd-live-debugger-ffi", path = "libdatadog/libdd-live-debugger-ffi", default-features = false } +libdd-live-debugger = { path = "libdatadog/libdd-live-debugger" } +libdd-live-debugger-ffi = { path = "libdatadog/libdd-live-debugger-ffi", default-features = false } libdd-ipc = { path = "libdatadog/libdd-ipc" } datadog-ffe = { package = "libdd-ffe", path = "libdatadog/libdd-ffe" } libdd-remote-config = { path = "libdatadog/libdd-remote-config" } diff --git a/cbindgen.toml b/cbindgen.toml index 50508ed52bd..dd4223ffb7e 100644 --- a/cbindgen.toml +++ b/cbindgen.toml @@ -46,8 +46,8 @@ include = [ "datadog-crashtracker-ffi", "datadog-sidecar", "libdd-ipc", - "datadog-live-debugger", - "datadog-live-debugger-ffi", + "libdd-live-debugger", + "libdd-live-debugger-ffi", "libdd-remote-config", "uuid" ] diff --git a/components-rs/remote_config.rs b/components-rs/remote_config.rs index 2bed8f0d67a..eadb02b0173 100644 --- a/components-rs/remote_config.rs +++ b/components-rs/remote_config.rs @@ -1,11 +1,11 @@ use crate::bytes::{dangling_zend_string, OwnedZendString, ZendString}; use crate::sidecar::MaybeShmLimiter; use datadog_ffe::rules_based::{Configuration, UniversalFlagConfig}; -use datadog_live_debugger::debugger_defs::{DebuggerData, DebuggerPayload}; -use datadog_live_debugger::{FilterList, LiveDebuggingData, ServiceConfiguration}; -use datadog_live_debugger_ffi::data::Probe; -use datadog_live_debugger_ffi::evaluator::{ddog_register_expr_evaluator, Evaluator}; -use datadog_live_debugger_ffi::send_data::{ +use libdd_live_debugger::debugger_defs::{DebuggerData, DebuggerPayload}; +use libdd_live_debugger::{FilterList, LiveDebuggingData, ServiceConfiguration}; +use libdd_live_debugger_ffi::data::Probe; +use libdd_live_debugger_ffi::evaluator::{ddog_register_expr_evaluator, Evaluator}; +use libdd_live_debugger_ffi::send_data::{ ddog_debugger_diagnostics_create_unboxed, ddog_snapshot_redacted_type, }; use datadog_sidecar::service::blocking::SidecarTransport; From 4296dbf5b28532c9de6889543806a655ef15bb70 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 4 Sep 2026 22:23:18 +0200 Subject: [PATCH 06/25] ci: switch macos test_c to Tart virtualized runner macos:sonoma-arm64 is now a project-runner tag reserved for a fixed allowlist of repos (datadog-ios, datadog-agent, etc); dd-trace-php isn't on it, so the job had no matching runner. Switch to the default arm64 macOS pool: tag macos:tart with an image pointing at a Tart VM OCI image in ECR. --- .gitlab/generate-tracer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index cde1f8ed01d..2255e272178 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -199,7 +199,8 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { "macos test_c": stage: test - tags: ["macos:sonoma-arm64"] + tags: ["macos:tart"] + image: "486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/ci-platform-machine-images/tart-vm:shared-sonoma-latest" variables: PHP_MACOS_VERSION: "8.5.7" PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" From b78b708bf60db022f323708671045be66f5f9e05 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 5 Sep 2026 03:44:03 +0200 Subject: [PATCH 07/25] fix(tests): pin DD_TRACE_RATE_LIMIT for test determinism Now that the sidecar stays up for the whole test_c run (previously it kept crash-looping, incidentally resetting the shared-memory rate limiter each time), the default 100 traces/sec limit becomes reachable for real: 717 tests across 4 concurrent workers can legitimately spike past it within the run, causing the local rate limiter to kick in and tag spans with a computed _dd.p.ksr rate instead of the deterministic _dd.p.dm=-0 that most tests' EXPECTF fixtures assume. Other non-deterministic sampling sources are already neutralized for tests (DD_TRACE_IGNORE_AGENT_SAMPLING_RATES, DD_TRACE_GIT_METADATA_ENABLED), but this one wasn't, since it never mattered before. Pin it to an effectively-unlimited value alongside the other overrides, and update config.phpt's expected telemetry dump for the new env-origin entry this introduces. Co-Authored-By: Claude Sonnet 5 --- Makefile | 2 +- tests/ext/telemetry/config.phpt | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 7b42ef09a8b..7f3cf1a7eb2 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ RUST_DEBUG_BUILD ?= $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo 1) EXTRA_CONFIGURE_OPTIONS ?= ASSUME_COMPILED := ${DD_TRACE_ASSUME_COMPILED} MAX_TEST_PARALLELISM ?= $(shell nproc) -ALL_TEST_ENV_OVERRIDE := $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1) DD_TRACE_GIT_METADATA_ENABLED=0 DD_CRASHTRACKER_RECEIVER_TIMEOUT_MS=15000 +ALL_TEST_ENV_OVERRIDE := $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1) DD_TRACE_GIT_METADATA_ENABLED=0 DD_CRASHTRACKER_RECEIVER_TIMEOUT_MS=15000 DD_TRACE_RATE_LIMIT=1000000 VERSION := $(shell cat VERSION) diff --git a/tests/ext/telemetry/config.phpt b/tests/ext/telemetry/config.phpt index 3fbbddba084..d3bc50bf10f 100644 --- a/tests/ext/telemetry/config.phpt +++ b/tests/ext/telemetry/config.phpt @@ -130,6 +130,15 @@ Array ) [6] => Array + ( + [name] => DD_TRACE_RATE_LIMIT + [value] => 1000000 + [origin] => env_var + [config_id] => + [seq_id] => + ) + + [7] => Array ( [name] => DD_TRACE_IGNORE_AGENT_SAMPLING_RATES [value] => 1 @@ -138,7 +147,7 @@ Array [seq_id] => ) - [7] => Array + [8] => Array ( [name] => DD_TRACE_GENERATE_ROOT_SPAN [value] => 0 @@ -147,7 +156,7 @@ Array [seq_id] => ) - [8] => Array + [9] => Array ( [name] => ssi_forced_injection_enabled [value] => False From 94eef2cfbea77a7ab354d238f916e3477fcecc71 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 5 Sep 2026 04:18:42 +0200 Subject: [PATCH 08/25] fix(tests): always ignore agent sampling rates and pin rate limit for test determinism DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 was only added to ALL_TEST_ENV_OVERRIDE when DD_TRACE_DOCKER_DEBUG was set -- which is true inside the Linux dev/CI Docker images but never on bare-metal runners (macOS Tart VMs, Windows). With the sidecar now staying up for the whole test_c run instead of crash-looping, its remote-config channel can actually deliver an agent-provided rate-by-service on these platforms, tagging spans with a computed _dd.p.ksr instead of the deterministic _dd.p.dm=-0 most .phpt EXPECTF fixtures assume. Make the flag unconditional so every platform gets the same deterministic sampling behavior, and set it (plus the same DD_TRACE_RATE_LIMIT override used elsewhere) explicitly for the Windows test_c job, which invokes run-tests.php directly rather than through make test_c. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 2255e272178..36eb074e9cf 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -152,7 +152,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { docker exec ${CONTAINER_NAME} powershell.exe "cd app; switch-php ; C:\php\SDK\phpize.bat; .\configure.bat --enable-debug-pack; nmake" # Set test environment variables - docker exec ${CONTAINER_NAME} powershell.exe "setx DD_AUTOLOAD_NO_COMPILE true; setx DATADOG_HAVE_DEV_ENV 1; setx DD_TRACE_GIT_METADATA_ENABLED 0" + docker exec ${CONTAINER_NAME} powershell.exe "setx DD_AUTOLOAD_NO_COMPILE true; setx DATADOG_HAVE_DEV_ENV 1; setx DD_TRACE_GIT_METADATA_ENABLED 0; setx DD_TRACE_IGNORE_AGENT_SAMPLING_RATES 1; setx DD_TRACE_RATE_LIMIT 1000000" # Exclude tests that deadlock the php-cgi SKIPIF skip-task on Windows. Date: Sat, 5 Sep 2026 05:06:03 +0200 Subject: [PATCH 09/25] debug: temporary instrumentation for agent-info env override + CI env dump Temporary, to be reverted once the source of the agent-provided default_env on the macOS CI runner is identified. --- .gitlab/generate-tracer.php | 2 ++ ext/agent_info.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 36eb074e9cf..5d1b23e59d0 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -206,6 +206,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" _DD_DEBUG_SIDECAR_LOG_LEVEL: trace _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log" + _DD_DEBUG_AGENT_INFO_FILE: "${CI_PROJECT_DIR}/artifacts/agent_info_debug.log" before_script: - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" @@ -234,6 +235,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" - php --version + - env | sort > "${CI_PROJECT_DIR}/artifacts/job_env.log" - make -j"$(sysctl -n hw.ncpu)" - timeout 20m make test_c after_script: diff --git a/ext/agent_info.c b/ext/agent_info.c index 4bea66668df..7d3e3f875c7 100644 --- a/ext/agent_info.c +++ b/ext/agent_info.c @@ -18,6 +18,15 @@ void datadog_apply_agent_info(void) { } ddog_CharSlice env = {0}, hash = {0}; ddog_apply_agent_info(DATADOG_G(agent_info_reader), &env, &hash); + const char *_dd_debug_path = getenv("_DD_DEBUG_AGENT_INFO_FILE"); + if (_dd_debug_path) { + FILE *_dd_debug_f = fopen(_dd_debug_path, "a"); + if (_dd_debug_f) { + fprintf(_dd_debug_f, "[DEBUG agent_info] pid=%d env_len=%zu env=%.*s cur_dd_env_len=%zu\n", + (int) getpid(), env.len, (int) env.len, env.len ? env.ptr : "", ZSTR_LEN(get_DD_ENV())); + fclose(_dd_debug_f); + } + } if (env.len && ZSTR_LEN(get_DD_ENV()) == 0) { zend_alter_ini_entry_chars( zai_config_memoized_entries[DATADOG_CONFIG_DD_ENV].ini_entries[0]->name, From 124b5d5390cb949aaac94faa3a6050402d641ce3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 5 Sep 2026 05:30:34 +0200 Subject: [PATCH 10/25] fix(ci): unset host-injected DD_AGENT_HOST/DD_TRACE_AGENT_PORT on macOS runner The macOS Tart VM runner (bare-metal, unlike containerized Linux jobs) has DD_AGENT_HOST=192.168.64.1 and DD_TRACE_AGENT_PORT=8126 injected into its environment, pointing at a real agent on the host (presumably for the runner's own infra monitoring). Confirmed via debug instrumentation: the sidecar's agent-info fetch was reaching that real agent and caching a genuine (if generic) "default_env": "none" in its shared session state, which then got applied to DD_ENV at runtime for every subsequent test process sharing that daemon -- since these env vars take precedence over the test harness's -d datadog.agent_host=... -d datadog.trace.agent_port=1 INI overrides, which are meant to guarantee no agent is reachable during tests. Unset them alongside the other DD_* vars GitLab already auto-injects for infra purposes (see unset_dd_runner_env_vars in generate-common.php), which this job's custom before_script wasn't calling. Reverts the temporary debug instrumentation and CI env dump added to diagnose this. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 11 +++++++++-- ext/agent_info.c | 9 --------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 5d1b23e59d0..5eca4383cda 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -206,8 +206,16 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" _DD_DEBUG_SIDECAR_LOG_LEVEL: trace _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log" - _DD_DEBUG_AGENT_INFO_FILE: "${CI_PROJECT_DIR}/artifacts/agent_info_debug.log" before_script: + # This bare-metal Tart VM has DD_AGENT_HOST/DD_TRACE_AGENT_PORT injected into + # its environment pointing at a real agent on the host (for the runner's own + # infra monitoring), unlike containerized Linux jobs. Those env vars take + # precedence over the test harness's `-d datadog.agent_host=... -d + # datadog.trace.agent_port=1` INI overrides meant to guarantee no agent is + # reachable, so the sidecar was reaching a real agent and getting back a + # real (if generic) "default_env", breaking test determinism. Unset these + # alongside the other DD_* vars GitLab auto-injects for infra purposes. + - unset DD_SERVICE DD_ENV DD_TAGS DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED DD_AGENT_HOST DD_TRACE_AGENT_PORT - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" - curl -fL "https://github.com/php/php-src/archive/refs/tags/php-${PHP_MACOS_VERSION}.tar.gz" | tar xz -C /tmp/php-build @@ -235,7 +243,6 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" - php --version - - env | sort > "${CI_PROJECT_DIR}/artifacts/job_env.log" - make -j"$(sysctl -n hw.ncpu)" - timeout 20m make test_c after_script: diff --git a/ext/agent_info.c b/ext/agent_info.c index 7d3e3f875c7..4bea66668df 100644 --- a/ext/agent_info.c +++ b/ext/agent_info.c @@ -18,15 +18,6 @@ void datadog_apply_agent_info(void) { } ddog_CharSlice env = {0}, hash = {0}; ddog_apply_agent_info(DATADOG_G(agent_info_reader), &env, &hash); - const char *_dd_debug_path = getenv("_DD_DEBUG_AGENT_INFO_FILE"); - if (_dd_debug_path) { - FILE *_dd_debug_f = fopen(_dd_debug_path, "a"); - if (_dd_debug_f) { - fprintf(_dd_debug_f, "[DEBUG agent_info] pid=%d env_len=%zu env=%.*s cur_dd_env_len=%zu\n", - (int) getpid(), env.len, (int) env.len, env.len ? env.ptr : "", ZSTR_LEN(get_DD_ENV())); - fclose(_dd_debug_f); - } - } if (env.len && ZSTR_LEN(get_DD_ENV()) == 0) { zend_alter_ini_entry_chars( zai_config_memoized_entries[DATADOG_CONFIG_DD_ENV].ini_entries[0]->name, From bcc4e7f38aa9b8350dcb0101cd5985143bb705b2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 5 Sep 2026 06:05:32 +0200 Subject: [PATCH 11/25] fix: macOS test_c CI flakiness (env leakage, log noise, SKIPIF gap) - Unset DD_DOGSTATSD_PORT alongside the other GitLab-injected DD_* env vars for the macOS test_c job, closing the last leak that let a real agent config reach the sidecar and break test determinism. - Downgrade the "INI not found" crashtracker setup log from DEBUG to TRACE: it fires on every setup when opcache/JIT aren't compiled in (as on the macOS CI build) and was polluting DD_TRACE_DEBUG=1 test diffs. - Skip force_flush_traces.phpt when the pcntl extension (and thus SIGKILL) isn't available. - Bump libdatadog to 025012a39, picking up the fix for a macOS SHM mapping panic when the size slot hasn't been committed yet. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 2 +- ext/signals.c | 5 ++++- tests/ext/force_flush_traces.phpt | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 5eca4383cda..e485a5f9ab7 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -215,7 +215,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { # reachable, so the sidecar was reaching a real agent and getting back a # real (if generic) "default_env", breaking test determinism. Unset these # alongside the other DD_* vars GitLab auto-injects for infra purposes. - - unset DD_SERVICE DD_ENV DD_TAGS DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED DD_AGENT_HOST DD_TRACE_AGENT_PORT + - unset DD_SERVICE DD_ENV DD_TAGS DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED DD_AGENT_HOST DD_TRACE_AGENT_PORT DD_DOGSTATSD_PORT - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" - curl -fL "https://github.com/php/php-src/archive/refs/tags/php-${PHP_MACOS_VERSION}.tar.gz" | tar xz -C /tmp/php-build diff --git a/ext/signals.c b/ext/signals.c index f9eb2b9c8f5..3ea6bda608c 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -150,7 +150,10 @@ static zend_always_inline zend_string *dd_crasht_find_ini_by_tag(ddog_CharSlice // On PHP 8.0+ these INI should all exist, but guard against the NULL case // in case something goes wrong, or this changes in a future version. if (UNEXPECTED(!value)) { - LOG(DEBUG, + // trace, not debug: this is expected whenever opcache/JIT aren't compiled in (e.g. + // the macOS CI build), and fires on every crashtracker setup, polluting test diffs + // captured with DD_TRACE_DEBUG=1. + LOG(TRACE, "crashtracker setup: INI \"%.*s\" not found (maybe compiled out in this PHP build)", (int) ini.len, ini.ptr); } diff --git a/tests/ext/force_flush_traces.phpt b/tests/ext/force_flush_traces.phpt index a5cb2dd776b..252758568b3 100644 --- a/tests/ext/force_flush_traces.phpt +++ b/tests/ext/force_flush_traces.phpt @@ -3,6 +3,7 @@ Force flush the traces mid-way through a trace --SKIPIF-- Date: Mon, 7 Sep 2026 17:01:20 +0200 Subject: [PATCH 12/25] Cleanup comments --- .gitlab/generate-tracer.php | 9 +-------- ext/signals.c | 3 --- tests/ext/telemetry/config.phpt | 1 + 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index e485a5f9ab7..e2de9de2e64 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -207,14 +207,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { _DD_DEBUG_SIDECAR_LOG_LEVEL: trace _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log" before_script: - # This bare-metal Tart VM has DD_AGENT_HOST/DD_TRACE_AGENT_PORT injected into - # its environment pointing at a real agent on the host (for the runner's own - # infra monitoring), unlike containerized Linux jobs. Those env vars take - # precedence over the test harness's `-d datadog.agent_host=... -d - # datadog.trace.agent_port=1` INI overrides meant to guarantee no agent is - # reachable, so the sidecar was reaching a real agent and getting back a - # real (if generic) "default_env", breaking test determinism. Unset these - # alongside the other DD_* vars GitLab auto-injects for infra purposes. + # Strip the noisy DD_* env vars from the locally installed agent - unset DD_SERVICE DD_ENV DD_TAGS DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED DD_AGENT_HOST DD_TRACE_AGENT_PORT DD_DOGSTATSD_PORT - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" diff --git a/ext/signals.c b/ext/signals.c index 3ea6bda608c..da323eca14c 100644 --- a/ext/signals.c +++ b/ext/signals.c @@ -150,9 +150,6 @@ static zend_always_inline zend_string *dd_crasht_find_ini_by_tag(ddog_CharSlice // On PHP 8.0+ these INI should all exist, but guard against the NULL case // in case something goes wrong, or this changes in a future version. if (UNEXPECTED(!value)) { - // trace, not debug: this is expected whenever opcache/JIT aren't compiled in (e.g. - // the macOS CI build), and fires on every crashtracker setup, polluting test diffs - // captured with DD_TRACE_DEBUG=1. LOG(TRACE, "crashtracker setup: INI \"%.*s\" not found (maybe compiled out in this PHP build)", (int) ini.len, ini.ptr); diff --git a/tests/ext/telemetry/config.phpt b/tests/ext/telemetry/config.phpt index d3bc50bf10f..30eb46f3ff5 100644 --- a/tests/ext/telemetry/config.phpt +++ b/tests/ext/telemetry/config.phpt @@ -25,6 +25,7 @@ DD_TRACE_RETRY_INTERVAL=1 DD_TRACE_GIT_METADATA_ENABLED=0 DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 DD_EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED=0 +DD_TRACE_RATE_LIMIT=1000000 --INI-- datadog.trace.agent_url="file://{PWD}/config-telemetry.out" --FILE-- From 8679cbd84a1f3840d772147f4d5f089a80593cc4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 9 Sep 2026 01:04:17 +0200 Subject: [PATCH 13/25] fix(ci): scope macOS-only test env overrides to Darwin, fix clippy CI break Two prior macOS test-determinism fixes had been applied unconditionally in the shared Makefile, breaking Linux CI: - ALL_TEST_ENV_OVERRIDE forced DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 on every platform, breaking tests/ext/background-sender/agent_sampling_sidecar.phpt, which specifically verifies behavior when agent sampling rates are NOT ignored. - RUN_TESTS_CMD unconditionally appended "-d datadog.agent_host=127.0.0.1 -d datadog.trace.agent_port=1", clobbering tests (e.g. tests/ext/live-debugger/debugger_log_probe_capture_size_limit.phpt) that explicitly point at the request-replayer mock agent via --ENV--. The env leakage these overrides guard against is specific to macOS's bare-metal CI runners, which GitLab auto-injects DD_* vars into for infra monitoring; Linux CI runs in Docker with no such stray agent and never needed either override. Scoped both to `uname -s` == Darwin, matching the existing pattern used for the macOS codesign step just below. Also bumps libdatadog to pick up a clippy::never_loop fix in datadog-sidecar/src/entry.rs that was breaking clippy/helper-rust CI jobs across every PHP version on Linux. Co-Authored-By: Claude Sonnet 5 --- Cargo.lock | 74 ++++++++++----------------------- Cargo.toml | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 14 ++++++- 3 files changed, 150 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a102d1172d8..89c8002e20a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,7 +310,7 @@ dependencies = [ "cfg-if", "libc 0.2.186", "miniz_oxide 0.8.9", - "object 0.36.7", + "object", "rustc-demangle", "windows-targets 0.52.6", ] @@ -1544,16 +1544,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" -[[package]] -name = "duplicate" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a4be4cd710e92098de6ad258e6e7c24af11c29c5142f3c6f2a545652480ff8" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", -] - [[package]] name = "duplicate" version = "2.0.1" @@ -1768,7 +1758,6 @@ checksum = "bc74ac4d8359ae70623506d512209619e5cf8f347124910440dbc221714b328e" dependencies = [ "borrow-or-share", "ref-cast", - "serde", ] [[package]] @@ -2825,7 +2814,7 @@ dependencies = [ "futures-channel", "futures-util", "http 1.4.2", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -2881,7 +2870,7 @@ dependencies = [ "serde", "static_assertions", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "tokio-rustls", "tower-service", @@ -2938,7 +2927,7 @@ dependencies = [ "symbolic-common", "symbolic-demangle", "tempfile", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "uuid", "windows 0.59.0", @@ -2973,7 +2962,7 @@ dependencies = [ "bytes", "clap", "criterion", - "duplicate 2.0.1", + "duplicate", "either", "futures", "getrandom 0.2.15", @@ -3018,7 +3007,7 @@ dependencies = [ [[package]] name = "libdd-data-pipeline-core" -version = "0.1.0" +version = "1.0.0" dependencies = [ "bytes", "futures", @@ -3029,7 +3018,7 @@ dependencies = [ "libdd-trace-obfuscation", "libdd-trace-utils", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", "zstd", ] @@ -3185,7 +3174,7 @@ dependencies = [ [[package]] name = "libdd-live-debugger" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "bytes", @@ -3252,7 +3241,7 @@ dependencies = [ "cxx", "cxx-build", "futures", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "http 1.4.2", "http-body-util", "httparse", @@ -3323,7 +3312,7 @@ dependencies = [ "sha2", "strum", "strum_macros", - "thiserror 1.0.69", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -3357,7 +3346,7 @@ dependencies = [ "bytes", "futures", "getrandom 0.2.15", - "hashbrown 0.15.2", + "hashbrown 0.17.1", "http 1.4.2", "httpmock", "libc 0.2.186", @@ -3417,7 +3406,7 @@ dependencies = [ "anyhow", "arbitrary", "criterion", - "duplicate 0.4.1", + "duplicate", "libdd-trace-protobuf", "rand 0.8.8", ] @@ -3428,7 +3417,7 @@ version = "8.0.0" dependencies = [ "anyhow", "criterion", - "duplicate 0.4.1", + "duplicate", "fluent-uri", "libdd-common", "libdd-tinybytes", @@ -3463,7 +3452,7 @@ dependencies = [ "async-trait", "criterion", "futures", - "hashbrown 0.15.2", + "hashbrown 0.17.1", "http 1.4.2", "httpmock", "libdd-capabilities", @@ -3496,6 +3485,7 @@ dependencies = [ "cargo-platform", "cargo_metadata", "criterion", + "crossbeam-channel", "flate2", "futures", "getrandom 0.2.15", @@ -3525,6 +3515,7 @@ dependencies = [ "serde_json", "tempfile", "thin-vec", + "thread_local", "tokio", "tracing", "urlencoding", @@ -3903,15 +3894,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -4098,24 +4080,15 @@ dependencies = [ "objc2-foundation", ] -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "flate2", - "memchr", - "ruzstd", -] - [[package]] name = "object" version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ + "flate2", "memchr", + "ruzstd", ] [[package]] @@ -4152,7 +4125,6 @@ dependencies = [ "objc2", "objc2-foundation", "objc2-ui-kit", - "serde", "windows-sys 0.61.2", ] @@ -5227,12 +5199,10 @@ dependencies = [ [[package]] name = "ruzstd" -version = "0.3.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a15e661f0f9dac21f3494fe5d23a6338c0ac116a2d22c2b63010acd89467ffe" +checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" dependencies = [ - "byteorder", - "thiserror 1.0.69", "twox-hash", ] @@ -5632,7 +5602,7 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" name = "sidecar_mockgen" version = "0.1.0" dependencies = [ - "object 0.31.1", + "object", ] [[package]] @@ -6435,7 +6405,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", - "nu-ansi-term", "once_cell", "regex-automata", "serde", @@ -6445,7 +6414,6 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", "tracing-serde", ] diff --git a/Cargo.toml b/Cargo.toml index fc8f7e3f9f4..902e2827919 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -155,44 +155,161 @@ inherits = "release" [workspace.dependencies] allocator-api2 = { version = "0.2.21", default-features = false } anyhow = { version = "1.0", default-features = false } +arbitrary = { version = "1.3", default-features = false } arc-swap = { version = "1.7.1", default-features = false } +arrayref = { version = "0.3.7", default-features = false } +assert_no_alloc = { version = "1.1.2", default-features = false } +async-trait = { version = "0.1", default-features = false } base64 = { version = "0.22", default-features = false } +bincode = { version = "1.3.3", default-features = false } +bitmaps = { version = "3.2.0", default-features = false } +blazesym = { version = "=0.2.3", default-features = false } bolero = { version = "0.13.4", default-features = false } +byteorder = { version = "1.5", default-features = false } bytes = { version = "1.11", default-features = false } +cadence = { version = "1.3.0", default-features = false } +cargo-platform = { version = "=0.1.7", default-features = false } +cargo_metadata = { version = "0.18.1", default-features = false } +cc = { version = "1.1.31", default-features = false } chrono = { version = "0.4.38", default-features = false } clap = { version = "4.3.21", default-features = false } +console-subscriber = { version = "0.5", default-features = false } +const_format = { version = "0.2.34", default-features = false } +constcat = { version = "0.4.1", default-features = false } criterion = { version = "0.5.1", default-features = true } +crossbeam-channel = { version = "0.5.15", default-features = false } +crossbeam-queue = { version = "0.3.11", default-features = false } +crossbeam-utils = { version = "0.8.21", default-features = false } +cxx = { version = "1.0", default-features = false } cxx-build = { version = "1.0", default-features = false } +derive_more = { version = "2.0.0", default-features = false } +duplicate = { version = "2.0.1", default-features = false } +either = { version = "1.13.0", default-features = false } elf = { version = "0.7", default-features = false } +errno = { version = "0.3", default-features = false } fastrand = { version = "2", default-features = false } +faststr = { version = "0.2.23", default-features = false } flate2 = { version = "1.0", default-features = false, features = ["rust_backend"] } +fluent-uri = { version = "0.4.1", default-features = false } +function_name = { version = "0.3.0", default-features = false } futures = { version = "0.3", default-features = false } +futures-channel = { version = "0.3", default-features = false } +futures-core = { version = "0.3.0", default-features = false } +futures-util = { version = "0.3.0", default-features = false } +getrandom = { version = "0.2", default-features = false } +glibc_version = { version = "0.1.2", default-features = false } +goblin = { version = "0.9.3", default-features = false } +h2 = { version = "0.4", default-features = false } +hashbrown = { version = "0.17", default-features = false } +heck = { version = "0.5", default-features = false } +hex = { version = "0.4", default-features = false } http = { version = "1.1", default-features = false } +http-body = { version = "1", default-features = false } http-body-util = { version = "0.1", default-features = false } httpmock = { version = "0.8.0-alpha.1", default-features = false, features = ["cookies"] } httparse = { version = "1.9", default-features = false } hyper = { version = "1.6", default-features = false } +hyper-rustls = { version = "0.27.7", default-features = false } hyper-util = { version = "0.1.10", default-features = false } +indexmap = { version = "2.11", default-features = false } io-lifetimes = { version = "1.0", default-features = false } +itoa = { version = "1.0", default-features = false } libc = { version = "0.2", default-features = true } +libdd-libunwind-sys = { version = "1.0.3", default-features = false } +log = { version = "0.4.21", default-features = false } +lru = { version = "0.16.3", default-features = false } +manual_future = { version = "0.1.1", default-features = false } +maplit = { version = "1.0", default-features = false } +md5 = { version = "0.7.0", default-features = false } +memfd = { version = "0.6", default-features = false } +memory-stats = { version = "1.2.0", default-features = false } +microseh = { version = "0.1.1", default-features = false } mime = { version = "0.3.16", default-features = false } +multer = { version = "3.1", default-features = false } +nix = { version = "0.29", default-features = false } +num-derive = { version = "0.4.2", default-features = false } +num-traits = { version = "0.2.19", default-features = false } +object = { version = "0.36", default-features = false } once_cell = { version = "1.18", default-features = false } +os_info = { version = "3.14.0", default-features = false } +page_size = { version = "0.6.0", default-features = false } +parking_lot = { version = "0.12", default-features = false } +paste = { version = "1", default-features = false } percent-encoding = { version = "2.1", default-features = false } +pin-project = { version = "1", default-features = false } +portable-atomic = { version = "1.6.0", default-features = false } +prctl = { version = "1.0.0", default-features = false } +pretty_assertions = { version = "1.3", default-features = false } +priority-queue = { version = "2.1.1", default-features = false } +proc-macro2 = { version = "1", default-features = false } +proptest = { version = "1", default-features = false } +prost = { version = "0.14.1", default-features = false } prost-build = { version = "0.14.1", default-features = false } protoc-bin-vendored = { version = "3.0.0", default-features = false } +pyo3 = { version = "0.28", default-features = false } +quote = { version = "1", default-features = false } +rand = { version = "0.8", default-features = false } +rand_chacha = { version = "0.3.1", default-features = false } regex = { version = "1.5", default-features = false } +regex-lite = { version = "0.1", default-features = false } reqwest = { version = "0.13", default-features = false } +ring = { version = "0.17", default-features = false } +rlimit = { version = "0.9", default-features = false } +rmp = { version = "0.8.14", default-features = false } +rmp-serde = { version = "1.3.0", default-features = false } +rmpv = { version = "1.3.0", default-features = false } +rustc-hash = { version = "2.1.1", default-features = false } rustls = { version = "0.23", default-features = false } +rustls-native-certs = { version = ">=0.8.1, <0.8.3", default-features = false } rustls-platform-verifier = { version = "0.6", default-features = false } +rustls-webpki = { version = ">=0.103.13", default-features = false } +schemars = { version = "0.8.21", default-features = false } +semver = { version = "1.0", default-features = false } +sendfd = { version = "0.4", default-features = false } serde = { version = "1.0", default-features = false } +serde-bool = { version = "0.1.3", default-features = false } +serde-transcode = { version = "1.1", default-features = false } +serde_bytes = { version = "0.11.9", default-features = false } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } +serde_with = { version = "3.11.0", default-features = false } +serde_yaml = { version = "0.9.34", default-features = false } +serial_test = { version = "3.2", default-features = false } sha2 = { version = "0.10", default-features = false } +simd-json = { version = "=0.14", default-features = false } +smallvec = { version = "1.13.2", default-features = false } +static_assertions = { version = "1.1.0", default-features = false } +strum = { version = "0.26.2", default-features = false } +strum_macros = { version = "0.26", default-features = false } +symbolic-common = { version = "12.8.0", default-features = false } +symbolic-demangle = { version = "12.8.0", default-features = false } syn = { version = "^2", default-features = false } +sys-info = { version = "0.9.0", default-features = false } +target-triple = { version = "0.1.4", default-features = false } tempfile = { version = "3.13", default-features = false, features = ["getrandom"] } +test-case = { version = "2.2", default-features = false } +thin-vec = { version = "0.2", default-features = false } +thiserror = { version = "2.0.3", default-features = false } +thread_local = { version = "1.1", default-features = false } +time = { version = "0.3", default-features = false } tokio = { version = "1.36", default-features = false } +tokio-rustls = { version = "0.26", default-features = false } +tokio-util = { version = "0.7.11", default-features = false } +tonic = { version = "0.14", default-features = false } +tower-service = { version = "0.3", default-features = false } tracing = { version = "0.1", default-features = false } +tracing-appender = { version = "0.2.3", default-features = false } +tracing-log = { version = "0.2.0", default-features = false } +tracing-subscriber = { version = "0.3.22", default-features = false } +tuf = { package = "libdd-tuf", version = "0.3.1", default-features = false } +url = { version = "2.5.0", default-features = false } +urlencoding = { version = "2.1.3", default-features = false } uuid = { version = "1.7.0", default-features = false } +wasm-bindgen-futures = { version = "0.4", default-features = false } +web-time = { version = "1", default-features = false } +winver = { version = "1.0.0", default-features = false } +zrip = { version = "=0.6.0", default-features = false } zstd = { version = "0.13", default-features = false } +zwohash = { version = "0.1.2", default-features = false } [workspace.lints] diff --git a/Makefile b/Makefile index f5e16b57467..f76fcd7e7f2 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,12 @@ RUST_DEBUG_BUILD ?= $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo 1) EXTRA_CONFIGURE_OPTIONS ?= ASSUME_COMPILED := ${DD_TRACE_ASSUME_COMPILED} MAX_TEST_PARALLELISM ?= $(shell nproc) -ALL_TEST_ENV_OVERRIDE := DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 DD_TRACE_GIT_METADATA_ENABLED=0 DD_CRASHTRACKER_RECEIVER_TIMEOUT_MS=15000 DD_TRACE_RATE_LIMIT=1000000 +# macOS CI runs on bare-metal runners that leak GitLab's infra-monitoring DD_* env vars into the +# job, letting the sidecar reach a real agent and breaking test determinism (varying sample rates, +# non-empty "env"). Linux CI runs in Docker with no such stray agent, and some tests (e.g. +# tests/ext/background-sender/agent_sampling_sidecar.phpt) specifically need agent sampling rates +# to NOT be ignored, so keep this macOS-only. +ALL_TEST_ENV_OVERRIDE := $(if $(filter Darwin,$(shell uname -s)),DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 DD_TRACE_RATE_LIMIT=1000000,$(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1)) DD_TRACE_GIT_METADATA_ENABLED=0 DD_CRASHTRACKER_RECEIVER_TIMEOUT_MS=15000 VERSION := $(shell cat VERSION) @@ -44,7 +49,12 @@ TRACER_SOURCES_INI := -d datadog.trace.sources_path=$(TRACER_SOURCE_DIR) RUN_TESTS_IS_PARALLEL ?= $(shell test $(PHP_MAJOR_MINOR) -ge 74 && echo 1) # shuffle parallel tests to evenly distribute test load, avoiding a batch of 32 tests being request-replayer tests -RUN_TESTS_CMD := DD_SERVICE= DD_ENV= REPORT_EXIT_STATUS=1 TEST_PHP_SRCDIR=$(PROJECT_ROOT) USE_TRACKED_ALLOC=1 php -n -d 'memory_limit=-1' $(BUILD_DIR)/run-tests.php $(if $(QUIET_TESTS),,-g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP) $(if $(ASAN), --asan) --show-diff -n -p $(shell which php) -q $(if $(RUN_TESTS_IS_PARALLEL), --shuffle -j$(MAX_TEST_PARALLELISM)) -d datadog.agent_host=127.0.0.1 -d datadog.trace.agent_port=1 +# +# On macOS CI, force a local, unreachable agent host/port so tests can't accidentally reach the +# real agent that GitLab's bare-metal runner env leakage would otherwise point them at (see +# ALL_TEST_ENV_OVERRIDE above). Linux tests that need a mock agent set DD_AGENT_HOST/DD_TRACE_AGENT_PORT +# explicitly via --ENV--, which a global -d override here would clobber. +RUN_TESTS_CMD := DD_SERVICE= DD_ENV= REPORT_EXIT_STATUS=1 TEST_PHP_SRCDIR=$(PROJECT_ROOT) USE_TRACKED_ALLOC=1 php -n -d 'memory_limit=-1' $(BUILD_DIR)/run-tests.php $(if $(QUIET_TESTS),,-g FAIL,XFAIL,BORK,WARN,LEAK,XLEAK,SKIP) $(if $(ASAN), --asan) --show-diff -n -p $(shell which php) -q $(if $(RUN_TESTS_IS_PARALLEL), --shuffle -j$(MAX_TEST_PARALLELISM)) $(if $(filter Darwin,$(shell uname -s)), -d datadog.agent_host=127.0.0.1 -d datadog.trace.agent_port=1) C_FILES = $(shell find components components-rs ext src/dogstatsd tracer zend_abstract_interface -name '*.c' -o -name '*.h' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) TEST_FILES = $(shell find tests/ext -name '*.php*' -o -name '*.inc' -o -name '*.json' -o -name '*.yaml' -o -name 'CONFLICTS' | awk '{ printf "$(BUILD_DIR)/%s\n", $$1 }' ) From cb029585a558aae17267a883b5df91302c325700 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 00:05:50 +0200 Subject: [PATCH 14/25] Skip test --- tests/ext/telemetry/broken_pipe.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ext/telemetry/broken_pipe.phpt b/tests/ext/telemetry/broken_pipe.phpt index 9bd666c7b43..c874db2e7ba 100644 --- a/tests/ext/telemetry/broken_pipe.phpt +++ b/tests/ext/telemetry/broken_pipe.phpt @@ -4,6 +4,7 @@ Telemetry test with connection reset From f3e9991073918ee00cb73cf889d950f22180ec0a Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 02:04:13 +0200 Subject: [PATCH 15/25] fix(ci): address Codex review of macOS test_c job - Skip segfault_backtrace_disabled.phpt on macOS with an accurate reason: with the default config, SIGSEGV handling is delegated entirely to libdatadog's crashtracker (ext/signals.c's own handler only installs when crashtracking is disabled), and on macOS the crashtracker's fork+receiver-process handling doesn't leave the process to die by/report the signal the way run-tests.php's Termsig detection expects. - Revert the broken_pipe.phpt Darwin skip added in a prior commit -- per Codex review, it was hiding a real macOS IPC issue (a timeout reconnecting after a forced broken connection) rather than a mere wording difference. Investigating for real instead of skipping. - Add --enable-pcntl to the macOS PHP build so pcntl-dependent tests (force_flush_traces.phpt, etc.) actually run on macOS CI instead of being silently skipped. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 1 + tests/ext/segfault_backtrace_disabled.phpt | 7 +++++++ tests/ext/telemetry/broken_pipe.phpt | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index e2de9de2e64..d20fbc22db0 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -223,6 +223,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { --prefix="${PHP_INSTALL_DIR}" \ --enable-debug \ --enable-zts \ + --enable-pcntl \ --without-iconv \ --with-openssl="$(brew --prefix openssl)" \ --with-libxml \ diff --git a/tests/ext/segfault_backtrace_disabled.phpt b/tests/ext/segfault_backtrace_disabled.phpt index 86430817ea7..7fcfc6cc077 100644 --- a/tests/ext/segfault_backtrace_disabled.phpt +++ b/tests/ext/segfault_backtrace_disabled.phpt @@ -5,6 +5,13 @@ Don't dump backtrace when segmentation fault signal is raised and config is defa if (!extension_loaded('posix')) die('skip: posix extension required'); if (getenv('SKIP_ASAN') || getenv('USE_ZEND_ALLOC') === '0') die("skip: intentionally causes segfaults"); if (file_exists("/etc/os-release") && preg_match("/alpine/i", file_get_contents("/etc/os-release"))) die("skip Unsupported LIBC"); +// With the default config (crashtracking enabled), SIGSEGV handling is delegated entirely to +// libdatadog's crashtracker (ext/signals.c's own handler only installs when crashtracking is +// disabled, see the mutual-exclusion check in ddtrace_signals_minit). On macOS the crashtracker's +// fork+receiver-process handling doesn't leave the process to die by/report the raw signal the +// way run-tests.php expects (neither "Segmentation fault" text nor a Termsig=11/exit-code-139 +// process result appears), unlike on Linux. +if (PHP_OS === "Darwin") die("skip: macOS crashtracker signal handling doesn't surface as Termsig=11/Segmentation fault the way run-tests.php expects"); ?> --ENV-- DD_LOG_BACKTRACE=0 diff --git a/tests/ext/telemetry/broken_pipe.phpt b/tests/ext/telemetry/broken_pipe.phpt index c874db2e7ba..9bd666c7b43 100644 --- a/tests/ext/telemetry/broken_pipe.phpt +++ b/tests/ext/telemetry/broken_pipe.phpt @@ -4,7 +4,6 @@ Telemetry test with connection reset From 8583c387a488b1de0f57456392591f2fbb98403d Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 02:15:22 +0200 Subject: [PATCH 16/25] chore: bump libdatadog for the macOS recv-liveness fix Picks up fix/macos-recv-liveness-detection, which addresses the real bug Codex found in tests/ext/telemetry/broken_pipe.phpt on macOS: recv_raw_blocking never watched the liveness pipe, so a daemon disconnecting mid-wait (e.g. after send_garbage causes the IPC serve loop to fail decoding and close its connection) went undetected until the whole read_timeout elapsed, then surfaced as a non-reconnectable TimedOut instead of BrokenPipe. Co-Authored-By: Claude Sonnet 5 --- libdatadog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdatadog b/libdatadog index 902002a1adb..2d658242877 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 902002a1adb24bc11b10b093a3053a106663f1dd +Subproject commit 2d658242877a633b3eba8767540f050f07c963de From 3a485a5365789f63209f3f25133ad29e2a3e660e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 02:39:37 +0200 Subject: [PATCH 17/25] fix(tests): skip extract_server_values.phpt on macOS Enabling --enable-pcntl on the macOS CI job (to fix issue #3 of the Codex review) exposed this test, which was previously skipped for lack of pcntl. It fails there because its re-exec trick reconstructs the process's full original argv (interpreter + its own -n/-d flags + script args) via Linux's /proc//cmdline; macOS has no portable equivalent without ext-ffi + sysctl(KERN_PROCARGS2). This is a test-infrastructure limitation, not a ddtrace behavior gap -- this test already runs (and presumably passes) on Linux CI today, unaffected by this change. $argv alone (tried first) is insufficient since it doesn't carry the interpreter's own flags needed to keep ddtrace loaded after the re-exec. Verified locally on macOS: test now skips cleanly instead of failing. Co-Authored-By: Claude Sonnet 5 --- tests/ext/extract_server_values.phpt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/ext/extract_server_values.phpt b/tests/ext/extract_server_values.phpt index 102f24d2d89..05f51ae9a07 100644 --- a/tests/ext/extract_server_values.phpt +++ b/tests/ext/extract_server_values.phpt @@ -1,7 +1,14 @@ --TEST-- Test invalid $_SERVER values are properly ignored --SKIPIF-- - +/cmdline exposes precisely and portably; macOS has no equivalent short of +// ext-ffi + sysctl(KERN_PROCARGS2). +if (PHP_OS === "Darwin") die('skip: re-exec via /proc//cmdline is Linux-only'); +?> --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_GENERATE_ROOT_SPAN=0 From e819c74ad1290ed34ebe58458f0e086e51e28740 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 04:53:45 +0200 Subject: [PATCH 18/25] fix(ci): resolve thread-mode sidecar shutdown hang on macOS bump libdatadog for the recv_raw_async liveness fix (root cause of the pcntl_fork_thread_mode_orphan.phpt hang: the server-side dispatch loop had no way to detect a disconnected macOS peer, so it waited indefinitely for the shutdown watchdog to see all connections close). Skip pcntl_fork_thread_mode_orphan.phpt on Darwin: with the hang fixed, the test now surfaces a separate, genuine macOS OS-level constraint -- kqueue fds don't survive fork(), so tokio's I/O driver panics with "Bad file descriptor" in the forked child. Thread mode is documented as not pcntl_fork()-safe; this only affects test coverage for the orphan-promotion scenario, not real usage (apps that fork already need subprocess mode). Co-Authored-By: Claude Sonnet 5 --- libdatadog | 2 +- tests/ext/pcntl/pcntl_fork_thread_mode_orphan.phpt | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libdatadog b/libdatadog index 2d658242877..9d158d1d8a9 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 2d658242877a633b3eba8767540f050f07c963de +Subproject commit 9d158d1d8a91c73f7e92779772cf32ac5fe5b10c diff --git a/tests/ext/pcntl/pcntl_fork_thread_mode_orphan.phpt b/tests/ext/pcntl/pcntl_fork_thread_mode_orphan.phpt index 14558a83316..838d1f7cc08 100644 --- a/tests/ext/pcntl/pcntl_fork_thread_mode_orphan.phpt +++ b/tests/ext/pcntl/pcntl_fork_thread_mode_orphan.phpt @@ -4,6 +4,18 @@ Thread mode sidecar: orphaned child process promotes itself to master after pare + --ENV-- DD_TRACE_SIDECAR_CONNECTION_MODE=thread DD_TRACE_GENERATE_ROOT_SPAN=0 From ef5311c8b0655d8eb4c9b7649300c1346fd12e83 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 05:01:32 +0200 Subject: [PATCH 19/25] ci(macos): run request-replayer natively to enable dev-env tests The macOS Tart runner has no Docker service network like the Linux/ Windows jobs' "request-replayer" service container, so tests gated by tests/ext/includes/skipif_no_dev_env.inc (checking DATADOG_HAVE_DEV_ENV) were unconditionally skipped there. Run request-replayer as a native background process on loopback instead: alias its hostname via /etc/hosts (most call sites hardcode "request-replayer" rather than reading DD_AGENT_HOST, e.g. tests/Common/TracerTestTrait.php), install its composer dependency with brew's php (bundles curl + gmp -- both required, see dockerfiles/services/request-replayer/linux.Dockerfile and index.php's UnpackOptions::BIGINT_AS_GMP), and start it on port 80. Validated locally end-to-end (native php -S bound to a loopback alias, /etc/hosts entry, DATADOG_HAVE_DEV_ENV=1): a previously-unrunnable dev-env-gated test (debugger_log_probe_capture_size_limit.phpt) passes. The CI wiring itself (sudo for the privileged port + /etc/hosts edit, brew's php formula) is unverified in the actual Tart runner environment and may need iteration. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index d20fbc22db0..d0896377133 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -206,10 +206,15 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" _DD_DEBUG_SIDECAR_LOG_LEVEL: trace _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log" + # Enables tests gated by tests/ext/includes/skipif_no_dev_env.inc (see request-replayer + # setup below), matching the Linux/Windows jobs' dev-env-dependent test coverage. + DATADOG_HAVE_DEV_ENV: 1 + PHP_CLI_SERVER_WORKERS: "16" + DD_REQUEST_DUMPER_FILE: dump.json before_script: # Strip the noisy DD_* env vars from the locally installed agent - unset DD_SERVICE DD_ENV DD_TAGS DD_TRACE_REMOVE_INTEGRATION_SERVICE_NAMES_ENABLED DD_AGENT_HOST DD_TRACE_AGENT_PORT DD_DOGSTATSD_PORT - - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium + - brew install pkg-config openssl re2c bison libxml2 oniguruma libzip libsodium php - mkdir -p /tmp/php-build "${CI_PROJECT_DIR}/artifacts/tests" - curl -fL "https://github.com/php/php-src/archive/refs/tags/php-${PHP_MACOS_VERSION}.tar.gz" | tar xz -C /tmp/php-build - cd "/tmp/php-build/php-src-php-${PHP_MACOS_VERSION}" @@ -233,6 +238,21 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - make install - cd "${CI_PROJECT_DIR}" - rustup update stable && rustup default stable + - | + # There's no Docker service network on the macOS Tart runner (unlike the Linux/Windows + # jobs' "request-replayer" service container), so run request-replayer as a native + # background process on loopback instead, and alias its hostname via /etc/hosts so + # tests that hardcode "request-replayer" (see tests/Common/TracerTestTrait.php et al.) + # resolve it the same way. Uses brew's php (bundles curl + gmp, both required -- see + # dockerfiles/services/request-replayer/linux.Dockerfile and index.php's + # UnpackOptions::BIGINT_AS_GMP) rather than our from-source test build, which has + # neither and is a separate, unrelated PHP install. + grep -q '[[:space:]]request-replayer$' /etc/hosts || sudo bash -c 'echo "127.0.0.1 request-replayer" >> /etc/hosts' + REQUEST_REPLAYER_PHP="$(brew --prefix php)/bin/php" + "${REQUEST_REPLAYER_PHP}" -r "copy('https://getcomposer.org/installer', '/tmp/composer-setup.php');" + "${REQUEST_REPLAYER_PHP}" /tmp/composer-setup.php --install-dir=/tmp --filename=composer.phar + (cd dockerfiles/services/request-replayer/src && "${REQUEST_REPLAYER_PHP}" /tmp/composer.phar install --no-interaction) + sudo bash -c "cd '${CI_PROJECT_DIR}/dockerfiles/services/request-replayer/src' && PHP_CLI_SERVER_WORKERS='${PHP_CLI_SERVER_WORKERS}' DD_REQUEST_DUMPER_FILE='${DD_REQUEST_DUMPER_FILE}' nohup '${REQUEST_REPLAYER_PHP}' -S 127.0.0.1:80 index.php > '${CI_PROJECT_DIR}/artifacts/request-replayer.log' 2>&1 & disown" script: - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" From b15b113647337357e2bdff5c1bfd267ad85bdaad Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 05:32:00 +0200 Subject: [PATCH 20/25] fix(ci): use sudo -b to background request-replayer, not shell & The CI job hung indefinitely after the test suite finished (confirmed via job trace: it stopped dead right after "make: *** [test_c] Error 1", with zero after_script output, for 2+ hours). Root cause: `sudo bash -c "... &"` backgrounds the php -S process inside the bash -c subshell, but non-interactive shells don't put background jobs in their own process group, so it stayed in sudo's process group. sudo with pty allocation (common on macOS) waits for the whole process group to exit before returning -- so the long-lived request-replayer server kept the whole job's script step from ever completing, even though its own stdout/stderr were redirected to a log file. Use `sudo -b`, sudo's own flag for backgrounding a command, so sudo itself returns immediately without waiting on the child. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index d0896377133..20a6d166b4f 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -252,7 +252,13 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { "${REQUEST_REPLAYER_PHP}" -r "copy('https://getcomposer.org/installer', '/tmp/composer-setup.php');" "${REQUEST_REPLAYER_PHP}" /tmp/composer-setup.php --install-dir=/tmp --filename=composer.phar (cd dockerfiles/services/request-replayer/src && "${REQUEST_REPLAYER_PHP}" /tmp/composer.phar install --no-interaction) - sudo bash -c "cd '${CI_PROJECT_DIR}/dockerfiles/services/request-replayer/src' && PHP_CLI_SERVER_WORKERS='${PHP_CLI_SERVER_WORKERS}' DD_REQUEST_DUMPER_FILE='${DD_REQUEST_DUMPER_FILE}' nohup '${REQUEST_REPLAYER_PHP}' -S 127.0.0.1:80 index.php > '${CI_PROJECT_DIR}/artifacts/request-replayer.log' 2>&1 & disown" + # `sudo -b` (not `sudo ... &`): a non-interactive shell's `&` doesn't put the + # backgrounded job in its own process group, so it stays in sudo's -- and sudo, + # with pty allocation (common on macOS), waits for the whole process group to exit + # before returning. That left the CI job hanging forever after the test suite + # finished. `-b` is sudo's own flag for backgrounding the command, so sudo itself + # returns immediately instead of waiting on this long-lived server. + sudo -b bash -c "cd '${CI_PROJECT_DIR}/dockerfiles/services/request-replayer/src' && PHP_CLI_SERVER_WORKERS='${PHP_CLI_SERVER_WORKERS}' DD_REQUEST_DUMPER_FILE='${DD_REQUEST_DUMPER_FILE}' exec '${REQUEST_REPLAYER_PHP}' -S 127.0.0.1:80 index.php < /dev/null > '${CI_PROJECT_DIR}/artifacts/request-replayer.log' 2>&1" script: - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" From 5b6db4918c8801548d613917e7e9143df9cbfcd3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 05:38:16 +0200 Subject: [PATCH 21/25] fix(tests): skip crashtracker and /proc-based re-exec tests on macOS Crashtracking isn't supported on macOS: the crash report never reaches the agent/request-replayer the way it does on Linux. Skip both crashtracker_segfault.phpt and crashtracker_segfault_disabled.phpt there (the latter also independently picks up macOS /bin/sh's own "Segmentation fault: 11" job-control notice on stderr, which isn't suppressed by the test's own "2>/dev/null"). rc_trace_enabled_rinit.phpt hits the same /proc//cmdline re-exec constraint already fixed for extract_server_values.phpt -- apply the same Darwin skip. These three tests were previously silently skipped by skipif_no_dev_env.inc (no DATADOG_HAVE_DEV_ENV in CI) and only surfaced now that the macOS job runs request-replayer natively. Co-Authored-By: Claude Sonnet 5 --- tests/ext/crashtracker_segfault.phpt | 4 ++++ tests/ext/crashtracker_segfault_disabled.phpt | 5 +++++ tests/ext/remote_config/rc_trace_enabled_rinit.phpt | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/tests/ext/crashtracker_segfault.phpt b/tests/ext/crashtracker_segfault.phpt index 0171930d6eb..d57cf99dd62 100644 --- a/tests/ext/crashtracker_segfault.phpt +++ b/tests/ext/crashtracker_segfault.phpt @@ -8,6 +8,10 @@ if (getenv('PHP_PEAR_RUNTESTS') === '1') die("skip: pecl run-tests does not supp if (getenv('DD_TRACE_CLI_ENABLED') === '0') die("skip: tracer is disabled"); if (PHP_VERSION_ID < 70200) die("skip: TEST_PHP_EXTRA_ARGS is only available on PHP 7.2+"); include __DIR__ . '/includes/skipif_no_dev_env.inc'; +// Crashtracking isn't supported on macOS: the crash report never reaches the agent/ +// request-replayer the way it does on Linux (see also segfault_backtrace_disabled.phpt's +// Darwin skip, which covers the related run-tests.php-visible-signal side of the same gap). +if (PHP_OS === "Darwin") die("skip: crashtracker is not supported on macOS"); ?> --ENV-- DD_TRACE_LOG_LEVEL=0 diff --git a/tests/ext/crashtracker_segfault_disabled.phpt b/tests/ext/crashtracker_segfault_disabled.phpt index 79e754a9182..5d63c167deb 100644 --- a/tests/ext/crashtracker_segfault_disabled.phpt +++ b/tests/ext/crashtracker_segfault_disabled.phpt @@ -8,6 +8,11 @@ if (getenv('PHP_PEAR_RUNTESTS') === '1') die("skip: pecl run-tests does not supp if (getenv('DD_TRACE_CLI_ENABLED') === '0') die("skip: tracer is disabled"); if (PHP_VERSION_ID < 70200) die("skip: TEST_PHP_EXTRA_ARGS is only available on PHP 7.2+"); include __DIR__ . '/includes/skipif_no_dev_env.inc'; +// Crashtracking isn't supported on macOS. Separately, this test's own diff also picks up +// macOS /bin/sh's own "Segmentation fault: 11" job-control notice on stderr (not suppressed +// by the test's own "2>/dev/null", which only covers the child's stderr) -- either issue +// alone would fail this test there. +if (PHP_OS === "Darwin") die("skip: crashtracker is not supported on macOS"); ?> --ENV-- DD_TRACE_LOG_LEVEL=0 diff --git a/tests/ext/remote_config/rc_trace_enabled_rinit.phpt b/tests/ext/remote_config/rc_trace_enabled_rinit.phpt index 4e7fc7e0cf2..a8cf3816b38 100644 --- a/tests/ext/remote_config/rc_trace_enabled_rinit.phpt +++ b/tests/ext/remote_config/rc_trace_enabled_rinit.phpt @@ -4,6 +4,10 @@ RC tracing_enabled=true during RINIT does not double-init request globals /cmdline exposes precisely and +// portably; macOS has no equivalent short of ext-ffi + sysctl(KERN_PROCARGS2). +if (PHP_OS === "Darwin") die('skip: re-exec via /proc//cmdline is Linux-only'); ?> --ENV-- DD_AGENT_HOST=request-replayer From fcaf2fe6b893fee9d3eb401600fbca783e7df8a2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 06:02:28 +0200 Subject: [PATCH 22/25] fix(ci): explicitly kill request-replayer instead of relying on detach sudo -b alone wasn't enough: the job hung again (confirmed via job trace -- test suite finished cleanly with 0 failures, but no after_script output followed, and the job sat idle for minutes). Whatever residual handle keeps the runner's output pipe open isn't fully understood, so rather than chase the exact detachment mechanism further, capture the server's PID when starting it and kill it explicitly in after_script, which runs regardless of script outcome. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 20a6d166b4f..28d26c0fdd8 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -255,10 +255,13 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { # `sudo -b` (not `sudo ... &`): a non-interactive shell's `&` doesn't put the # backgrounded job in its own process group, so it stays in sudo's -- and sudo, # with pty allocation (common on macOS), waits for the whole process group to exit - # before returning. That left the CI job hanging forever after the test suite - # finished. `-b` is sudo's own flag for backgrounding the command, so sudo itself - # returns immediately instead of waiting on this long-lived server. - sudo -b bash -c "cd '${CI_PROJECT_DIR}/dockerfiles/services/request-replayer/src' && PHP_CLI_SERVER_WORKERS='${PHP_CLI_SERVER_WORKERS}' DD_REQUEST_DUMPER_FILE='${DD_REQUEST_DUMPER_FILE}' exec '${REQUEST_REPLAYER_PHP}' -S 127.0.0.1:80 index.php < /dev/null > '${CI_PROJECT_DIR}/artifacts/request-replayer.log' 2>&1" + # before returning. `-b` is sudo's own flag for backgrounding the command, so sudo + # itself returns immediately instead of waiting on this long-lived server. Even so, + # explicitly kill the server in after_script below (via its captured PID) rather than + # relying purely on detachment: the job still hung once even with -b, most likely + # some other inherited handle back to the runner's own output pipe, and killing it + # outright sidesteps whatever that is rather than chasing it further. + sudo -b bash -c "cd '${CI_PROJECT_DIR}/dockerfiles/services/request-replayer/src' && PHP_CLI_SERVER_WORKERS='${PHP_CLI_SERVER_WORKERS}' DD_REQUEST_DUMPER_FILE='${DD_REQUEST_DUMPER_FILE}' nohup '${REQUEST_REPLAYER_PHP}' -S 127.0.0.1:80 index.php < /dev/null > '${CI_PROJECT_DIR}/artifacts/request-replayer.log' 2>&1 & echo \$! > '${CI_PROJECT_DIR}/artifacts/request-replayer.pid'" script: - export PATH="${PHP_INSTALL_DIR}/bin:${PATH}" - export TEST_PHP_JUNIT="${CI_PROJECT_DIR}/artifacts/tests/php-tests.xml" @@ -268,6 +271,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { after_script: - mkdir -p "${CI_PROJECT_DIR}/artifacts/diffs" - find . -type f \( -name '*.diff' -o -name '*.mem' \) -not -path '*/vendor/*' -exec cp '{}' "${CI_PROJECT_DIR}/artifacts/diffs/" \; || true + - test -f "${CI_PROJECT_DIR}/artifacts/request-replayer.pid" && sudo kill -9 "$(cat "${CI_PROJECT_DIR}/artifacts/request-replayer.pid")" || true artifacts: when: always reports: From 1b0206e351f37da124b9f9a7fdf113bcd16bba26 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 14:28:42 +0200 Subject: [PATCH 23/25] fix(ci): kill request-replayer inside script:, not only after_script Found the actual mechanism via the job trace: GitLab's own timeout fired on "step_script" (before_script + script combined) after 1h, with after_script never starting at all -- the test suite had finished cleanly (0 failures) 50 minutes earlier. So the hang is in step_script itself never returning, meaning the after_script-only kill added in fcaf2fe6b never got a chance to run. Most likely explanation: request-replayer runs as root (via sudo), and gitlab-runner's own process-tree cleanup, running as the unprivileged CI user, cannot signal it -- so whatever wait it performs before concluding step_script blocks forever on a process it can't kill, until GitLab's outer 1h job timeout intervenes. Kill it explicitly (with our own passwordless sudo) as the last line of script: itself, so nothing survives for the runner's own cleanup to wait on. Kept the after_script kill too as a backstop for a script: that fails before reaching that line. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index 28d26c0fdd8..b2be6d023a4 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -268,6 +268,13 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { - php --version - make -j"$(sysctl -n hw.ncpu)" - timeout 20m make test_c + # GitLab's "step_script" (before_script + script) itself doesn't return while + # request-replayer is still alive -- confirmed by a run where the test suite finished + # cleanly (0 failures) but the job then sat idle until GitLab's own 1h job timeout + # killed it, with after_script never even starting. So kill it here, at the end of + # script itself, not only in after_script (kept below as a backstop for a failing + # script: that never reaches this line). + - test -f "${CI_PROJECT_DIR}/artifacts/request-replayer.pid" && sudo kill -9 "$(cat "${CI_PROJECT_DIR}/artifacts/request-replayer.pid")" || true after_script: - mkdir -p "${CI_PROJECT_DIR}/artifacts/diffs" - find . -type f \( -name '*.diff' -o -name '*.mem' \) -not -path '*/vendor/*' -exec cp '{}' "${CI_PROJECT_DIR}/artifacts/diffs/" \; || true From 21ae6befe7468c58201333ea3fdc333ed2f3def3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 15:32:03 +0200 Subject: [PATCH 24/25] ci(macos): add curl, sockets, ffi to unlock more test coverage These were missing configure flags, not real platform gaps -- verified locally that --with-curl/--enable-sockets/--with-ffi build cleanly and all three extensions load and function (curl_init, socket_create, FFI class all present). This unlocks the "curl extension required" (26), "sockets extension is required" (5), and "ffi extension required" (2) skips from the macOS test_c run. Enabling ffi surfaces a fourth crashtracker test (crashtracker_collect_all_threads.phpt, gated on both dev-env and ffi) that was never exercised before; skip it on Darwin for the same reason as the other three crashtracker tests. Note: opcache.so is not produced by this build (libtool reports "whether to build shared libraries... no" even with opcache otherwise enabled and functional -- extension_loaded("Zend OPcache") is true), so the 5 tests that check for the physical .so file's existence still skip. Left uninvestigated for now. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 5 ++++- tests/ext/crashtracker_collect_all_threads.phpt | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index b2be6d023a4..ca03ac31d8a 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -233,7 +233,10 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { --with-openssl="$(brew --prefix openssl)" \ --with-libxml \ --enable-mbstring \ - --with-sodium + --with-sodium \ + --with-curl \ + --enable-sockets \ + --with-ffi - make -j"$(sysctl -n hw.ncpu)" - make install - cd "${CI_PROJECT_DIR}" diff --git a/tests/ext/crashtracker_collect_all_threads.phpt b/tests/ext/crashtracker_collect_all_threads.phpt index 5fa111c08ee..f4c6502914d 100644 --- a/tests/ext/crashtracker_collect_all_threads.phpt +++ b/tests/ext/crashtracker_collect_all_threads.phpt @@ -10,6 +10,9 @@ if (PHP_VERSION_ID < 70200) die("skip: TEST_PHP_EXTRA_ARGS is only available on if (!extension_loaded('ffi')) die('skip: ffi extension required'); if (!trim(shell_exec('which cc 2>/dev/null') ?: shell_exec('which gcc 2>/dev/null') ?: '')) die('skip: C compiler not available'); include __DIR__ . '/includes/skipif_no_dev_env.inc'; +// Crashtracking isn't supported on macOS: the crash report never reaches the agent/ +// request-replayer the way it does on Linux (see also crashtracker_segfault.phpt's Darwin skip). +if (PHP_OS === "Darwin") die("skip: crashtracker is not supported on macOS"); ?> --ENV-- DD_TRACE_LOG_LEVEL=0 From dd1480ee038de3f59a6f60f67a78fd6c9705c1ee Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Sep 2026 17:29:47 +0200 Subject: [PATCH 25/25] ci(macos): bump PHP to 8.5.9, fixing a tailcall-VM vm_interrupt crash debugger_log_probe_capture_timeout.phpt (a dev-env-gated test, never exercised on macOS until this session's CI work turned DATADOG_HAVE_DEV_ENV on) crashed reproducibly on macOS with EXC_BAD_ACCESS in ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER: execute_data->call was NULL where the VM expected a valid pending call frame. Traced it to a genuine PHP core bug, not a ddtrace bug: on ZEND_VM_KIND_TAILCALL builds (used on macOS/ARM64, unlike Linux's HYBRID VM), a VM interrupt handled right as a tailcall returns to its caller didn't save the opline first, corrupting the caller's in-flight call setup for its next statement. Confirmed via lldb: the crash follows immediately after a dd_vm_interrupt-triggered ddog_process_remote_configs() call lands on the top-level script frame right between two statements. Fixed upstream in PHP 8.5.8 ("Fix another vm_interrupt bug for tailcall VM", GH-22265, commit 05c7b00d796). Verified locally: reproduced the crash 3/3 times on 8.5.7, and it's gone 6/6 times after rebuilding against 8.5.9. Co-Authored-By: Claude Sonnet 5 --- .gitlab/generate-tracer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/generate-tracer.php b/.gitlab/generate-tracer.php index ca03ac31d8a..dc581481f49 100644 --- a/.gitlab/generate-tracer.php +++ b/.gitlab/generate-tracer.php @@ -202,7 +202,7 @@ function windows_test_c_job($job_name, $thread_safety, $targets) { tags: ["macos:tart"] image: "486234852809.dkr.ecr.us-east-1.amazonaws.com/ci/ci-platform-machine-images/tart-vm:shared-sonoma-latest" variables: - PHP_MACOS_VERSION: "8.5.7" + PHP_MACOS_VERSION: "8.5.9" PHP_INSTALL_DIR: "/tmp/php-macos-${PHP_MACOS_VERSION}" _DD_DEBUG_SIDECAR_LOG_LEVEL: trace _DD_DEBUG_SIDECAR_LOG_METHOD: "file://${CI_PROJECT_DIR}/artifacts/sidecar.log"