diff --git a/.circleci/continue_config.yml b/.circleci/continue_config.yml index 8cd701b767..24e4358763 100644 --- a/.circleci/continue_config.yml +++ b/.circleci/continue_config.yml @@ -311,6 +311,13 @@ aliases: machine: image: ubuntu-2004:current + - &STEP_SET_CORE_PATTERN + run: + name: Set core pattern + command: | + sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + + commands: git_checkout: parameters: @@ -943,10 +950,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE - - run: - name: Set core pattern - command: | - sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_httpbin_and_request_replayer @@ -975,6 +979,7 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find /tmp -name "core*" -type f | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/$(if [[ << parameters.make_target >> == *opcache* ]]; then echo opcache; else echo ext; fi) /tmp/artifacts/tests when: on_fail - store_artifacts: @@ -1000,10 +1005,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE - - run: - name: Set core pattern - command: | - sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_httpbin_and_request_replayer @@ -1027,7 +1029,9 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find /tmp -name "core*" -type f | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests + find /tmp/artifacts/tests -name '*.phpt' -delete when: on_fail - store_artifacts: path: /tmp/artifacts @@ -1051,10 +1055,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE - - run: - name: Set core pattern - command: | - sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_httpbin_and_request_replayer @@ -1080,7 +1081,9 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find /tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests + find /tmp/artifacts/tests -name '*.phpt' -delete when: on_fail - store_artifacts: path: /tmp/artifacts @@ -1150,10 +1153,7 @@ jobs: sudo useradd -u 3434 docker-circleci sudo chown -R docker-circleci . tests # - <<: *STEP_WAIT_REQUEST_REPLAYER - - run: - name: Set core pattern - command: | - sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + - <<: *STEP_SET_CORE_PATTERN - run: name: Run tests command: | @@ -1181,6 +1181,7 @@ jobs: mkdir -p /tmp/artifacts/core_dumps find /tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests + find /tmp/artifacts/tests -name '*.phpt' -delete when: on_fail - store_artifacts: path: /tmp/artifacts @@ -1265,10 +1266,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE - - run: - name: Set core pattern - command: | - sudo sh -c "echo '/tmp/core.%e.%p.%t' > /proc/sys/kernel/core_pattern" + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_httpbin_and_request_replayer @@ -1306,6 +1304,7 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find /tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests when: on_fail - store_artifacts: @@ -1720,6 +1719,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_snapshots @@ -1759,12 +1759,15 @@ jobs: command: | set -euo pipefail <<# parameters.coverage >>unset CI && unset CIRCLECI && export DD_AUTOLOAD_NO_COMPILE=true<> - DD_TRACE_AGENT_TIMEOUT=1000 <<# parameters.disable_runner_distributed_tracing >> DD_DISTRIBUTED_TRACING=false <> DD_TRACE_TEST_SAPI=<< parameters.sapi >> make << parameters.make_target >> PHPUNIT_OPTS="--log-junit test-results/php-composer/results-<< parameters.make_target >>.xml" + _DD_DEBUG_SIDECAR_LOG_METHOD=file://$(pwd)/tests/sidecar.log DD_TRACE_AGENT_TIMEOUT=1000 <<# parameters.disable_runner_distributed_tracing >> DD_DISTRIBUTED_TRACING=false <> DD_TRACE_TEST_SAPI=<< parameters.sapi >> make << parameters.make_target >> PHPUNIT_OPTS="--log-junit test-results/php-composer/results-<< parameters.make_target >>.xml" - <<: *STEP_CODE_COVERAGE - run: command: | mkdir -p /tmp/artifacts - find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' -o -name 'core*' \) -exec cp --parents '{}' /tmp/artifacts \; + find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' -o -name 'sidecar.log' \) -exec cp --parents '{}' /tmp/artifacts \; + mkdir -p /tmp/artifacts/core_dumps + find /tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ when: on_fail - store_artifacts: path: /tmp/artifacts/ @@ -1853,12 +1856,13 @@ jobs: command: | set -euo pipefail <<# parameters.coverage >>unset CI && unset CIRCLECI && export DD_AUTOLOAD_NO_COMPILE=true<> - DD_TRACE_AGENT_TIMEOUT=1000 <<# parameters.disable_runner_distributed_tracing >> DD_DISTRIBUTED_TRACING=false <> DD_TRACE_TEST_SAPI=<< parameters.sapi >> make << parameters.make_target >> RUST_DEBUG_BUILD=1 PHPUNIT_OPTS="--log-junit test-results/php-composer/results.xml" + _DD_DEBUG_SIDECAR_LOG_METHOD=file://$(pwd)/tests/sidecar.log DD_TRACE_AGENT_TIMEOUT=1000 <<# parameters.disable_runner_distributed_tracing >> DD_DISTRIBUTED_TRACING=false <> DD_TRACE_TEST_SAPI=<< parameters.sapi >> make << parameters.make_target >> RUST_DEBUG_BUILD=1 PHPUNIT_OPTS="--log-junit test-results/php-composer/results.xml" - <<: *STEP_CODE_COVERAGE - run: command: | mkdir -p /tmp/artifacts - find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' -o -name 'core*' \) -exec cp --parents '{}' /tmp/artifacts \; + find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' -o -name 'sidecar.log' -o -name 'core' -o -name 'core.*' \) -exec cp --parents '{}' /tmp/artifacts \; + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ when: on_fail - store_artifacts: path: /tmp/artifacts/ @@ -1982,6 +1986,7 @@ jobs: - source-v1-{{ .Branch }}-{{ .Revision }} - git_checkout - <<: *STEP_ATTACH_WORKSPACE + - <<: *STEP_SET_CORE_PATTERN - setup_docker: docker_image: datadog/dd-trace-ci:php-<< parameters.php_major_minor >>_buster extra: with_snapshots @@ -2018,7 +2023,10 @@ jobs: - run: command: | mkdir -p /tmp/artifacts - find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' -o -name 'core*' \) -exec cp --parents '{}' /tmp/artifacts \; + find ~/datadog/tests -type f \( -name 'phpunit_error.log' -o -name 'nginx_*.log' -o -name 'apache_*.log' -o -name 'php_fpm_*.log' -o -name 'dd_php_error.log' \) -exec cp --parents '{}' /tmp/artifacts \; + mkdir -p /tmp/artifacts/core_dumps + find /tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ when: on_fail - store_artifacts: path: /tmp/artifacts/ @@ -2093,7 +2101,9 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests + find /tmp/artifacts/tests -name '*.phpt' -delete when: on_fail - store_artifacts: path: /tmp/artifacts @@ -2145,7 +2155,9 @@ jobs: command: | mkdir -p /tmp/artifacts/core_dumps find tmp -name "core.*" | xargs -I % -n 1 cp % /tmp/artifacts/core_dumps + ! [ "$(ls -A /tmp/artifacts/core_dumps)" ] || cp tmp/build_extension/modules/ddtrace.so /tmp/artifacts/ cp -a tmp/build_extension/tests/ext /tmp/artifacts/tests + find /tmp/artifacts/tests -name '*.phpt' -delete when: on_fail - store_artifacts: path: /tmp/artifacts @@ -5307,6 +5319,10 @@ workflows: - test_c_disabled - test_internal_api_randomized - test_opcache + exclude: + # apparently for no discernible reason, on PHP 8.1 valgrind thinks some extensions are loaded, but they aren't. We anyway test sasn, so good enough, I guess. + - php_major_minor: '8.1' + make_target: test_c2php - test: requires: [ 'Prepare Code' ] diff --git a/Cargo.lock b/Cargo.lock index 23d0a3be86..a1fd7fdc7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1279,6 +1279,7 @@ dependencies = [ "datadog-trace-protobuf", "datadog-trace-utils", "ddcommon 0.0.1", + "ddtelemetry", "dogstatsd-client", "either", "futures", @@ -1286,6 +1287,7 @@ dependencies = [ "hyper 0.14.32", "log", "rand 0.8.5", + "regex", "rmp-serde", "serde", "serde_json", @@ -1700,6 +1702,7 @@ dependencies = [ "rmpv", "serde", "serde_json", + "tempfile", "testcontainers", "tinybytes", "tokio", @@ -1837,7 +1840,7 @@ dependencies = [ "ddtelemetry", "ddtelemetry-ffi", "env_logger 0.10.2", - "http 0.2.11", + "http 0.2.12", "itertools 0.11.0", "lazy_static", "log", diff --git a/Makefile b/Makefile index b8cd8fbd75..23b0eae36f 100644 --- a/Makefile +++ b/Makefile @@ -25,18 +25,19 @@ AR_FILE = $(BUILD_DIR)/modules/ddtrace.a WALL_FLAGS = -Wall -Wextra CFLAGS ?= $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo -O0 || echo -O2) -g $(WALL_FLAGS) LDFLAGS ?= -PHP_EXTENSION_DIR = $(shell ASAN_OPTIONS=detect_leaks=0 php -r 'print ini_get("extension_dir");') -PHP_MAJOR_MINOR = $(shell ASAN_OPTIONS=detect_leaks=0 php -r 'echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;') +PHP_EXTENSION_DIR = $(shell ASAN_OPTIONS=detect_leaks=0 php -d ddtrace.disable=1 -r 'print ini_get("extension_dir");') +PHP_MAJOR_MINOR = $(shell ASAN_OPTIONS=detect_leaks=0 php -n -r 'echo PHP_MAJOR_VERSION . PHP_MINOR_VERSION;') ARCHITECTURE = $(shell uname -m) QUIET_TESTS := ${CIRCLE_SHA1} 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 VERSION := $(shell cat VERSION) -INI_FILE := $(shell ASAN_OPTIONS=detect_leaks=0 php -i | awk -F"=>" '/Scan this dir for additional .ini files/ {print $$2}')/ddtrace.ini +INI_FILE := $(shell ASAN_OPTIONS=detect_leaks=0 php -d ddtrace.disable=1 -i | awk -F"=>" '/Scan this dir for additional .ini files/ {print $$2}')/ddtrace.ini RUN_TESTS_IS_PARALLEL ?= $(shell test $(PHP_MAJOR_MINOR) -ge 74 && echo 1) @@ -154,10 +155,10 @@ install_appsec: install_all: install install_ini run_tests: $(TEST_FILES) $(TEST_STUB_FILES) $(BUILD_DIR)/run-tests.php - DD_TRACE_GIT_METADATA_ENABLED=0 $(RUN_TESTS_CMD) $(TESTS) + $(ALL_TEST_ENV_OVERRIDE) $(RUN_TESTS_CMD) $(TESTS) test_c: $(SO_FILE) $(TEST_FILES) $(TEST_STUB_FILES) $(BUILD_DIR)/run-tests.php - $(if $(ASAN), USE_ZEND_ALLOC=0 USE_TRACKED_ALLOC=1 LSAN_OPTIONS=fast_unwind_on_malloc=0$${LSAN_OPTIONS:+$(,)$${LSAN_OPTIONS}}) DD_TRACE_GIT_METADATA_ENABLED=0 $(RUN_TESTS_CMD) -d extension=$(SO_FILE) $(BUILD_DIR)/$(subst $(BUILD_DIR_NAME)/,,$(TESTS)) + $(if $(ASAN), USE_ZEND_ALLOC=0 USE_TRACKED_ALLOC=1 LSAN_OPTIONS=fast_unwind_on_malloc=0$${LSAN_OPTIONS:+$(,)$${LSAN_OPTIONS}}) $(ALL_TEST_ENV_OVERRIDE) $(RUN_TESTS_CMD) -d extension=$(SO_FILE) $(BUILD_DIR)/$(subst $(BUILD_DIR_NAME)/,,$(TESTS)) test_c_coverage: dist_clean DD_TRACE_DOCKER_DEBUG=1 EXTRA_CFLAGS="-fprofile-arcs -ftest-coverage" $(MAKE) test_c || exit 0 @@ -169,7 +170,7 @@ test_c_disabled: $(SO_FILE) $(TEST_FILES) $(TEST_STUB_FILES) $(BUILD_DIR)/run-te ) test_c_observer: $(SO_FILE) $(TEST_FILES) $(TEST_STUB_FILES) $(BUILD_DIR)/run-tests.php - $(if $(ASAN), USE_ZEND_ALLOC=0 USE_TRACKED_ALLOC=1) DD_TRACE_GIT_METADATA_ENABLED=0 $(RUN_TESTS_CMD) -d extension=$(SO_FILE) -d extension=zend_test.so -d zend_test.observer.enabled=1 -d zend_test.observer.observe_all=1 -d zend_test.observer.show_output=0 $(BUILD_DIR)/$(TESTS) + $(if $(ASAN), USE_ZEND_ALLOC=0 USE_TRACKED_ALLOC=1) $(ALL_TEST_ENV_OVERRIDE) $(RUN_TESTS_CMD) -d extension=$(SO_FILE) -d extension=zend_test.so -d zend_test.observer.enabled=1 -d zend_test.observer.observe_all=1 -d zend_test.observer.show_output=0 $(BUILD_DIR)/$(TESTS) test_opcache: $(SO_FILE) $(TEST_OPCACHE_FILES) $(BUILD_DIR)/run-tests.php $(if $(ASAN), USE_ZEND_ALLOC=0 USE_TRACKED_ALLOC=1) $(RUN_TESTS_CMD) -d extension=$(SO_FILE) -d zend_extension=opcache.so $(BUILD_DIR)/tests/opcache @@ -196,12 +197,11 @@ test_extension_ci: $(SO_FILE) $(TEST_FILES) $(TEST_STUB_FILES) $(BUILD_DIR)/run- set -xe; \ export PATH="$(PROJECT_ROOT)/tests/ext/valgrind:$$PATH"; \ export TEST_PHP_JUNIT=$(JUNIT_RESULTS_DIR)/normal-extension-test.xml; \ - export DD_TRACE_GIT_METADATA_ENABLED=0; \ - $(RUN_TESTS_CMD) -d extension=$(SO_FILE) $(BUILD_DIR)/$(TESTS); \ + $(ALL_TEST_ENV_OVERRIDE) $(RUN_TESTS_CMD) -d extension=$(SO_FILE) $(BUILD_DIR)/$(TESTS); \ \ export TEST_PHP_JUNIT=$(JUNIT_RESULTS_DIR)/valgrind-extension-test.xml; \ export TEST_PHP_OUTPUT=$(JUNIT_RESULTS_DIR)/valgrind-run-tests.out; \ - $(RUN_TESTS_CMD) -d extension=$(SO_FILE) -m -s $$TEST_PHP_OUTPUT $(BUILD_DIR)/$(TESTS) && ! grep -e 'LEAKED TEST SUMMARY' $$TEST_PHP_OUTPUT; \ + $(ALL_TEST_ENV_OVERRIDE) $(RUN_TESTS_CMD) -d extension=$(SO_FILE) -m -s $$TEST_PHP_OUTPUT $(BUILD_DIR)/$(TESTS) && ! grep -e 'LEAKED TEST SUMMARY' $$TEST_PHP_OUTPUT; \ ) build_tea: TEA_BUILD_TESTS=ON @@ -526,7 +526,7 @@ cores: # TESTS ######################################################################################################################## TRACER_SOURCES_INI := -d datadog.trace.sources_path=$(TRACER_SOURCE_DIR) -ENV_OVERRIDE := $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo DD_AUTOLOAD_NO_COMPILE=true DD_TRACE_SOURCES_PATH=$(TRACER_SOURCE_DIR)) DD_DOGSTATSD_URL=http://request-replayer:80 DD_TRACE_GIT_METADATA_ENABLED=false +ENV_OVERRIDE := $(shell [ -n "${DD_TRACE_DOCKER_DEBUG}" ] && echo DD_AUTOLOAD_NO_COMPILE=true DD_TRACE_SOURCES_PATH=$(TRACER_SOURCE_DIR)) DD_DOGSTATSD_URL=http://request-replayer:80 $(ALL_TEST_ENV_OVERRIDE) TEST_EXTRA_INI ?= TEST_EXTRA_ENV ?= @@ -1046,6 +1046,52 @@ TEST_WEB_83 := \ test_web_custom \ test_web_zend_1_21 +TEST_INTEGRATIONS_84 := \ + test_integrations_amqp2 \ + test_integrations_amqp_latest \ + test_integrations_curl \ + test_integrations_deferred_loading \ + test_integrations_kafka \ + test_integrations_laminaslog2 \ + test_integrations_memcache \ + test_integrations_memcached \ + test_integrations_mongodb_latest \ + test_integrations_monolog1 \ + test_integrations_monolog2 \ + test_integrations_monolog_latest \ + test_integrations_mysqli \ + test_integrations_openai_latest \ + test_opentelemetry_1 \ + test_integrations_googlespanner_latest \ + test_integrations_guzzle_latest \ + test_integrations_pcntl \ + test_integrations_pdo \ + test_integrations_elasticsearch7 \ + test_integrations_elasticsearch_latest \ + test_integrations_predis_latest \ + test_integrations_frankenphp \ + test_integrations_roadrunner \ + test_integrations_sqlsrv \ + test_integrations_swoole_5 \ + test_opentracing_10 + +TEST_WEB_84 := \ + test_metrics \ + test_web_cakephp_latest \ + test_web_codeigniter_22 \ + test_web_codeigniter_31 \ + test_web_laravel_octane_latest \ + test_web_lumen_100 \ + test_web_nette_latest \ + test_web_slim_312 \ + test_web_symfony_latest \ + test_web_wordpress_59 \ + test_web_wordpress_61 \ + test_web_custom \ + test_web_zend_1_21 + +# to check: test_web_drupal_95, test_web_laravel_latest, test_web_slim_latest, test_integrations_phpredis6 + FILTER ?= . MAX_RETRIES := 3 @@ -1288,9 +1334,11 @@ test_integrations_frankenphp: global_test_run_dependencies test_integrations_roadrunner: global_test_run_dependencies tests/Frameworks/Roadrunner/Version_2/composer.lock-php$(PHP_MAJOR_MINOR) $(call run_tests_debug,tests/Integrations/Roadrunner/V2) test_integrations_googlespanner_latest: global_test_run_dependencies tests/Integrations/GoogleSpanner/Latest/composer.lock-php$(PHP_MAJOR_MINOR) + $(eval TEST_EXTRA_ENV=ZEND_DONT_UNLOAD_MODULES=1) $(eval TEST_EXTRA_INI=-d extension=grpc.so) $(call run_tests_debug,tests/Integrations/GoogleSpanner/Latest) $(eval TEST_EXTRA_INI=) + $(eval TEST_EXTRA_ENV=) test_integrations_sqlsrv: global_test_run_dependencies $(eval TEST_EXTRA_INI=-d extension=sqlsrv.so) $(call run_tests_debug,tests/Integrations/SQLSRV) diff --git a/components-rs/common.h b/components-rs/common.h index 24428507cd..2614f4c304 100644 --- a/components-rs/common.h +++ b/components-rs/common.h @@ -369,8 +369,6 @@ typedef enum ddog_RemoteConfigProduct { DDOG_REMOTE_CONFIG_PRODUCT_ASM, DDOG_REMOTE_CONFIG_PRODUCT_ASM_DD, DDOG_REMOTE_CONFIG_PRODUCT_ASM_FEATURES, - DDOG_REMOTE_CONFIG_PRODUCT_ASM_RASP_LFI, - DDOG_REMOTE_CONFIG_PRODUCT_ASM_RASP_SSRF, DDOG_REMOTE_CONFIG_PRODUCT_LIVE_DEBUGGER, } ddog_RemoteConfigProduct; @@ -872,7 +870,6 @@ typedef enum ddog_crasht_BuildIdType { DDOG_CRASHT_BUILD_ID_TYPE_GNU, DDOG_CRASHT_BUILD_ID_TYPE_GO, DDOG_CRASHT_BUILD_ID_TYPE_PDB, - DDOG_CRASHT_BUILD_ID_TYPE_PE, DDOG_CRASHT_BUILD_ID_TYPE_SHA1, } ddog_crasht_BuildIdType; @@ -890,7 +887,7 @@ typedef enum ddog_crasht_ErrorKind { typedef enum ddog_crasht_FileType { DDOG_CRASHT_FILE_TYPE_APK, DDOG_CRASHT_FILE_TYPE_ELF, - DDOG_CRASHT_FILE_TYPE_PDB, + DDOG_CRASHT_FILE_TYPE_PE, } ddog_crasht_FileType; /** @@ -938,16 +935,45 @@ typedef enum ddog_crasht_SiCodes { DDOG_CRASHT_SI_CODES_SI_TKILL, DDOG_CRASHT_SI_CODES_SI_USER, DDOG_CRASHT_SI_CODES_SYS_SECCOMP, + DDOG_CRASHT_SI_CODES_UNKNOWN, } ddog_crasht_SiCodes; /** * See https://man7.org/linux/man-pages/man7/signal.7.html */ typedef enum ddog_crasht_SignalNames { + DDOG_CRASHT_SIGNAL_NAMES_SIGHUP, + DDOG_CRASHT_SIGNAL_NAMES_SIGINT, + DDOG_CRASHT_SIGNAL_NAMES_SIGQUIT, + DDOG_CRASHT_SIGNAL_NAMES_SIGILL, + DDOG_CRASHT_SIGNAL_NAMES_SIGTRAP, DDOG_CRASHT_SIGNAL_NAMES_SIGABRT, DDOG_CRASHT_SIGNAL_NAMES_SIGBUS, + DDOG_CRASHT_SIGNAL_NAMES_SIGFPE, + DDOG_CRASHT_SIGNAL_NAMES_SIGKILL, + DDOG_CRASHT_SIGNAL_NAMES_SIGUSR1, DDOG_CRASHT_SIGNAL_NAMES_SIGSEGV, + DDOG_CRASHT_SIGNAL_NAMES_SIGUSR2, + DDOG_CRASHT_SIGNAL_NAMES_SIGPIPE, + DDOG_CRASHT_SIGNAL_NAMES_SIGALRM, + DDOG_CRASHT_SIGNAL_NAMES_SIGTERM, + DDOG_CRASHT_SIGNAL_NAMES_SIGCHLD, + DDOG_CRASHT_SIGNAL_NAMES_SIGCONT, + DDOG_CRASHT_SIGNAL_NAMES_SIGSTOP, + DDOG_CRASHT_SIGNAL_NAMES_SIGTSTP, + DDOG_CRASHT_SIGNAL_NAMES_SIGTTIN, + DDOG_CRASHT_SIGNAL_NAMES_SIGTTOU, + DDOG_CRASHT_SIGNAL_NAMES_SIGURG, + DDOG_CRASHT_SIGNAL_NAMES_SIGXCPU, + DDOG_CRASHT_SIGNAL_NAMES_SIGXFSZ, + DDOG_CRASHT_SIGNAL_NAMES_SIGVTALRM, + DDOG_CRASHT_SIGNAL_NAMES_SIGPROF, + DDOG_CRASHT_SIGNAL_NAMES_SIGWINCH, + DDOG_CRASHT_SIGNAL_NAMES_SIGIO, DDOG_CRASHT_SIGNAL_NAMES_SIGSYS, + DDOG_CRASHT_SIGNAL_NAMES_SIGEMT, + DDOG_CRASHT_SIGNAL_NAMES_SIGINFO, + DDOG_CRASHT_SIGNAL_NAMES_UNKNOWN, } ddog_crasht_SignalNames; /** @@ -971,9 +997,6 @@ typedef struct ddog_crasht_CrashInfo ddog_crasht_CrashInfo; typedef struct ddog_crasht_CrashInfoBuilder ddog_crasht_CrashInfoBuilder; -/** - * All fields are hex encoded integers. - */ typedef struct ddog_crasht_StackFrame ddog_crasht_StackFrame; typedef struct ddog_crasht_StackTrace ddog_crasht_StackTrace; @@ -1017,6 +1040,20 @@ typedef struct ddog_crasht_Slice_CharSlice { uintptr_t len; } ddog_crasht_Slice_CharSlice; +typedef struct ddog_crasht_Slice_I32 { + /** + * Should be non-null and suitably aligned for the underlying type. It is + * allowed but not recommended for the pointer to be null when the len is + * zero. + */ + const int32_t *ptr; + /** + * The number of elements (not bytes) that `.ptr` points to. Must be less + * than or equal to [isize::MAX]. + */ + uintptr_t len; +} ddog_crasht_Slice_I32; + typedef struct ddog_crasht_Config { struct ddog_crasht_Slice_CharSlice additional_files; bool create_alt_stack; @@ -1027,6 +1064,11 @@ typedef struct ddog_crasht_Config { */ const struct ddog_Endpoint *endpoint; enum ddog_crasht_StacktraceCollection resolve_frames; + /** + * The set of signals we should be registered for. + * If empty, use the default set. + */ + struct ddog_crasht_Slice_I32 signals; /** * Timeout in milliseconds before the signal handler starts tearing things down to return. * This is given as a uint32_t, but the actual timeout needs to fit inside of an i32 (max @@ -1082,6 +1124,20 @@ typedef struct ddog_crasht_Metadata { const struct ddog_Vec_Tag *tags; } ddog_crasht_Metadata; +typedef struct ddog_crasht_Slice_CInt { + /** + * Should be non-null and suitably aligned for the underlying type. It is + * allowed but not recommended for the pointer to be null when the len is + * zero. + */ + const int *ptr; + /** + * The number of elements (not bytes) that `.ptr` points to. Must be less + * than or equal to [isize::MAX]. + */ + uintptr_t len; +} ddog_crasht_Slice_CInt; + /** * A generic result type for when an operation may fail, * or may return in case of success. @@ -1119,38 +1175,13 @@ typedef struct ddog_crasht_Handle_CrashInfoBuilder { struct ddog_crasht_CrashInfoBuilder *inner; } ddog_crasht_Handle_CrashInfoBuilder; -/** - * A generic result type for when an operation may fail, - * or may return in case of success. - */ -typedef enum ddog_crasht_Result_HandleCrashInfoBuilder_Tag { - DDOG_CRASHT_RESULT_HANDLE_CRASH_INFO_BUILDER_OK_HANDLE_CRASH_INFO_BUILDER, - DDOG_CRASHT_RESULT_HANDLE_CRASH_INFO_BUILDER_ERR_HANDLE_CRASH_INFO_BUILDER, -} ddog_crasht_Result_HandleCrashInfoBuilder_Tag; - -typedef struct ddog_crasht_Result_HandleCrashInfoBuilder { - ddog_crasht_Result_HandleCrashInfoBuilder_Tag tag; - union { - struct { - struct ddog_crasht_Handle_CrashInfoBuilder ok; - }; - struct { - struct ddog_Error err; - }; - }; -} ddog_crasht_Result_HandleCrashInfoBuilder; - -/** - * A generic result type for when an operation may fail, - * or may return in case of success. - */ -typedef enum ddog_crasht_Result_HandleCrashInfo_Tag { - DDOG_CRASHT_RESULT_HANDLE_CRASH_INFO_OK_HANDLE_CRASH_INFO, - DDOG_CRASHT_RESULT_HANDLE_CRASH_INFO_ERR_HANDLE_CRASH_INFO, -} ddog_crasht_Result_HandleCrashInfo_Tag; +typedef enum ddog_crasht_CrashInfo_NewResult_Tag { + DDOG_CRASHT_CRASH_INFO_NEW_RESULT_OK, + DDOG_CRASHT_CRASH_INFO_NEW_RESULT_ERR, +} ddog_crasht_CrashInfo_NewResult_Tag; -typedef struct ddog_crasht_Result_HandleCrashInfo { - ddog_crasht_Result_HandleCrashInfo_Tag tag; +typedef struct ddog_crasht_CrashInfo_NewResult { + ddog_crasht_CrashInfo_NewResult_Tag tag; union { struct { struct ddog_crasht_Handle_CrashInfo ok; @@ -1159,7 +1190,7 @@ typedef struct ddog_crasht_Result_HandleCrashInfo { struct ddog_Error err; }; }; -} ddog_crasht_Result_HandleCrashInfo; +} ddog_crasht_CrashInfo_NewResult; typedef struct ddog_crasht_OsInfo { ddog_CharSlice architecture; @@ -1216,17 +1247,13 @@ typedef struct ddog_crasht_Handle_StackFrame { struct ddog_crasht_StackFrame *inner; } ddog_crasht_Handle_StackFrame; -/** - * A generic result type for when an operation may fail, - * or may return in case of success. - */ -typedef enum ddog_crasht_Result_HandleStackFrame_Tag { - DDOG_CRASHT_RESULT_HANDLE_STACK_FRAME_OK_HANDLE_STACK_FRAME, - DDOG_CRASHT_RESULT_HANDLE_STACK_FRAME_ERR_HANDLE_STACK_FRAME, -} ddog_crasht_Result_HandleStackFrame_Tag; +typedef enum ddog_crasht_StackFrame_NewResult_Tag { + DDOG_CRASHT_STACK_FRAME_NEW_RESULT_OK, + DDOG_CRASHT_STACK_FRAME_NEW_RESULT_ERR, +} ddog_crasht_StackFrame_NewResult_Tag; -typedef struct ddog_crasht_Result_HandleStackFrame { - ddog_crasht_Result_HandleStackFrame_Tag tag; +typedef struct ddog_crasht_StackFrame_NewResult { + ddog_crasht_StackFrame_NewResult_Tag tag; union { struct { struct ddog_crasht_Handle_StackFrame ok; @@ -1235,59 +1262,24 @@ typedef struct ddog_crasht_Result_HandleStackFrame { struct ddog_Error err; }; }; -} ddog_crasht_Result_HandleStackFrame; - -/** - * A generic result type for when an operation may fail, - * or may return in case of success. - */ -typedef enum ddog_crasht_Result_HandleStackTrace_Tag { - DDOG_CRASHT_RESULT_HANDLE_STACK_TRACE_OK_HANDLE_STACK_TRACE, - DDOG_CRASHT_RESULT_HANDLE_STACK_TRACE_ERR_HANDLE_STACK_TRACE, -} ddog_crasht_Result_HandleStackTrace_Tag; - -typedef struct ddog_crasht_Result_HandleStackTrace { - ddog_crasht_Result_HandleStackTrace_Tag tag; - union { - struct { - struct ddog_crasht_Handle_StackTrace ok; - }; - struct { - struct ddog_Error err; - }; - }; -} ddog_crasht_Result_HandleStackTrace; - -/** - * A wrapper for returning owned strings from FFI - */ -typedef struct ddog_crasht_StringWrapper { - /** - * This is a String stuffed into the vec. - */ - struct ddog_Vec_U8 message; -} ddog_crasht_StringWrapper; +} ddog_crasht_StackFrame_NewResult; -/** - * A generic result type for when an operation may fail, - * or may return in case of success. - */ -typedef enum ddog_crasht_Result_StringWrapper_Tag { - DDOG_CRASHT_RESULT_STRING_WRAPPER_OK_STRING_WRAPPER, - DDOG_CRASHT_RESULT_STRING_WRAPPER_ERR_STRING_WRAPPER, -} ddog_crasht_Result_StringWrapper_Tag; +typedef enum ddog_StringWrapperResult_Tag { + DDOG_STRING_WRAPPER_RESULT_OK, + DDOG_STRING_WRAPPER_RESULT_ERR, +} ddog_StringWrapperResult_Tag; -typedef struct ddog_crasht_Result_StringWrapper { - ddog_crasht_Result_StringWrapper_Tag tag; +typedef struct ddog_StringWrapperResult { + ddog_StringWrapperResult_Tag tag; union { struct { - struct ddog_crasht_StringWrapper ok; + struct ddog_StringWrapper ok; }; struct { struct ddog_Error err; }; }; -} ddog_crasht_Result_StringWrapper; +} ddog_StringWrapperResult; #ifdef __cplusplus extern "C" { diff --git a/components-rs/crashtracker.h b/components-rs/crashtracker.h index c5e4464c13..f2c0d661c3 100644 --- a/components-rs/crashtracker.h +++ b/components-rs/crashtracker.h @@ -12,6 +12,40 @@ #include #include "common.h" +typedef enum ddog_crasht_CrashInfoBuilder_NewResult_Tag { + DDOG_CRASHT_CRASH_INFO_BUILDER_NEW_RESULT_OK, + DDOG_CRASHT_CRASH_INFO_BUILDER_NEW_RESULT_ERR, +} ddog_crasht_CrashInfoBuilder_NewResult_Tag; + +typedef struct ddog_crasht_CrashInfoBuilder_NewResult { + ddog_crasht_CrashInfoBuilder_NewResult_Tag tag; + union { + struct { + struct ddog_crasht_Handle_CrashInfoBuilder ok; + }; + struct { + struct ddog_Error err; + }; + }; +} ddog_crasht_CrashInfoBuilder_NewResult; + +typedef enum ddog_crasht_StackTrace_NewResult_Tag { + DDOG_CRASHT_STACK_TRACE_NEW_RESULT_OK, + DDOG_CRASHT_STACK_TRACE_NEW_RESULT_ERR, +} ddog_crasht_StackTrace_NewResult_Tag; + +typedef struct ddog_crasht_StackTrace_NewResult { + ddog_crasht_StackTrace_NewResult_Tag tag; + union { + struct { + struct ddog_crasht_Handle_StackTrace ok; + }; + struct { + struct ddog_Error err; + }; + }; +} ddog_crasht_StackTrace_NewResult; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -92,6 +126,52 @@ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_init_without_receiver(struct ddog_crasht_Config config, struct ddog_crasht_Metadata metadata); +/** + * Returns a list of signals suitable for use in a crashtracker config. + */ +struct ddog_crasht_Slice_CInt ddog_crasht_default_signals(void); + +/** + * Removes all existing additional tags + * Expected to be used after a fork, to reset the additional tags on the child + * ATOMICITY: + * This is NOT ATOMIC. + * Should only be used when no conflicting updates can occur, + * e.g. after a fork but before profiling ops start on the child. + * # Safety + * No safety concerns. + */ +DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_clear_additional_tags(void); + +/** + * Atomically registers a string as an additional tag. + * Useful for tracking what operations were occurring when a crash occurred. + * The set does not check for duplicates. + * + * Returns: + * Ok(handle) on success. The handle is needed to later remove the id; + * Err() on failure. The most likely cause of failure is that the underlying set is full. + * + * # Safety + * The string argument must be valid. + */ +DDOG_CHECK_RETURN +struct ddog_crasht_Result_Usize ddog_crasht_insert_additional_tag(ddog_CharSlice s); + +/** + * Atomically removes a completed SpanId. + * Useful for tracking what operations were occurring when a crash occurred. + * 0 is reserved for "NoId" + * + * Returns: + * `Ok` on success. + * `Err` on failure. + * + * # Safety + * No safety concerns. + */ +DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_remove_additional_tag(uintptr_t idx); + /** * Resets all counters to 0. * Expected to be used after a fork, to reset the counters on the child @@ -291,7 +371,7 @@ struct ddog_VoidResult ddog_crasht_CrashInfo_upload_to_endpoint(struct ddog_cras * No safety issues. */ DDOG_CHECK_RETURN -struct ddog_crasht_Result_HandleCrashInfoBuilder ddog_crasht_CrashInfoBuilder_new(void); +struct ddog_crasht_CrashInfoBuilder_NewResult ddog_crasht_CrashInfoBuilder_new(void); /** * # Safety @@ -306,7 +386,7 @@ void ddog_crasht_CrashInfoBuilder_drop(struct ddog_crasht_Handle_CrashInfoBuilde * which has not previously been dropped. */ DDOG_CHECK_RETURN -struct ddog_crasht_Result_HandleCrashInfo ddog_crasht_CrashInfoBuilder_build(struct ddog_crasht_Handle_CrashInfoBuilder *builder); +struct ddog_crasht_CrashInfo_NewResult ddog_crasht_CrashInfoBuilder_build(struct ddog_crasht_Handle_CrashInfoBuilder *builder); /** * # Safety @@ -378,7 +458,8 @@ struct ddog_VoidResult ddog_crasht_CrashInfoBuilder_with_incomplete(struct ddog_ */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_CrashInfoBuilder_with_log_message(struct ddog_crasht_Handle_CrashInfoBuilder *builder, - ddog_CharSlice message); + ddog_CharSlice message, + bool also_print); /** * # Safety @@ -514,7 +595,7 @@ struct ddog_VoidResult ddog_crasht_CrashInfoBuilder_with_uuid_random(struct ddog * # Safety * No safety issues. */ -DDOG_CHECK_RETURN struct ddog_crasht_Result_HandleStackFrame ddog_crasht_StackFrame_new(void); +DDOG_CHECK_RETURN struct ddog_crasht_StackFrame_NewResult ddog_crasht_StackFrame_new(void); /** * # Safety @@ -531,7 +612,7 @@ void ddog_crasht_StackFrame_drop(struct ddog_crasht_Handle_StackFrame *frame); */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_StackFrame_with_ip(struct ddog_crasht_Handle_StackFrame *frame, - ddog_CharSlice ip); + uintptr_t ip); /** * # Safety @@ -541,7 +622,7 @@ struct ddog_VoidResult ddog_crasht_StackFrame_with_ip(struct ddog_crasht_Handle_ */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_StackFrame_with_module_base_address(struct ddog_crasht_Handle_StackFrame *frame, - ddog_CharSlice module_base_address); + uintptr_t module_base_address); /** * # Safety @@ -551,7 +632,7 @@ struct ddog_VoidResult ddog_crasht_StackFrame_with_module_base_address(struct dd */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_StackFrame_with_sp(struct ddog_crasht_Handle_StackFrame *frame, - ddog_CharSlice sp); + uintptr_t sp); /** * # Safety @@ -561,7 +642,7 @@ struct ddog_VoidResult ddog_crasht_StackFrame_with_sp(struct ddog_crasht_Handle_ */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_StackFrame_with_symbol_address(struct ddog_crasht_Handle_StackFrame *frame, - ddog_CharSlice symbol_address); + uintptr_t symbol_address); /** * # Safety @@ -611,7 +692,7 @@ struct ddog_VoidResult ddog_crasht_StackFrame_with_path(struct ddog_crasht_Handl */ DDOG_CHECK_RETURN struct ddog_VoidResult ddog_crasht_StackFrame_with_relative_address(struct ddog_crasht_Handle_StackFrame *frame, - ddog_CharSlice relative_address); + uintptr_t relative_address); /** * # Safety @@ -656,7 +737,7 @@ struct ddog_VoidResult ddog_crasht_StackFrame_with_line(struct ddog_crasht_Handl * # Safety * No safety issues. */ -DDOG_CHECK_RETURN struct ddog_crasht_Result_HandleStackTrace ddog_crasht_StackTrace_new(void); +DDOG_CHECK_RETURN struct ddog_crasht_StackTrace_NewResult ddog_crasht_StackTrace_new(void); /** * # Safety @@ -695,8 +776,8 @@ struct ddog_VoidResult ddog_crasht_StackTrace_set_complete(struct ddog_crasht_Ha * The string is copied into the result, and does not need to outlive this call */ DDOG_CHECK_RETURN -struct ddog_crasht_Result_StringWrapper ddog_crasht_demangle(ddog_CharSlice name, - enum ddog_crasht_DemangleOptions options); +struct ddog_StringWrapperResult ddog_crasht_demangle(ddog_CharSlice name, + enum ddog_crasht_DemangleOptions options); /** * Receives data from a crash collector via a pipe on `stdin`, formats it into diff --git a/components-rs/sidecar.h b/components-rs/sidecar.h index 549415bfbc..02d5b77f4f 100644 --- a/components-rs/sidecar.h +++ b/components-rs/sidecar.h @@ -194,7 +194,8 @@ ddog_MaybeError ddog_sidecar_session_set_config(struct ddog_SidecarTransport **t const enum ddog_RemoteConfigProduct *remote_config_products, uintptr_t remote_config_products_count, const enum ddog_RemoteConfigCapabilities *remote_config_capabilities, - uintptr_t remote_config_capabilities_count); + uintptr_t remote_config_capabilities_count, + bool is_fork); /** * Sends a trace to the sidecar via shared memory. diff --git a/dockerfiles/ci/xfail_tests/8.1.list b/dockerfiles/ci/xfail_tests/8.1.list index 2015e626a7..ffc0693a5d 100644 --- a/dockerfiles/ci/xfail_tests/8.1.list +++ b/dockerfiles/ci/xfail_tests/8.1.list @@ -51,6 +51,7 @@ ext/json/tests/json_encode_exceptions.phpt ext/mbstring/tests/zend_multibyte-01.phpt ext/mbstring/tests/zend_multibyte-02.phpt ext/mbstring/tests/zend_multibyte-06.phpt +ext/mysqli/tests/ghsa-h35g-vwh6-m678-stmt-row-double.phpt ext/openssl/tests/bug46127.phpt ext/openssl/tests/bug48182.phpt ext/openssl/tests/bug54992.phpt diff --git a/dockerfiles/ci/xfail_tests/8.2.list b/dockerfiles/ci/xfail_tests/8.2.list index 90cb979663..f588fd51d8 100644 --- a/dockerfiles/ci/xfail_tests/8.2.list +++ b/dockerfiles/ci/xfail_tests/8.2.list @@ -52,6 +52,7 @@ ext/json/tests/json_encode_exceptions.phpt ext/mbstring/tests/zend_multibyte-01.phpt ext/mbstring/tests/zend_multibyte-02.phpt ext/mbstring/tests/zend_multibyte-06.phpt +ext/mysqli/tests/ghsa-h35g-vwh6-m678-stmt-row-double.phpt ext/openssl/tests/bug46127.phpt ext/openssl/tests/bug48182.phpt ext/openssl/tests/bug54992.phpt diff --git a/ext/configuration.h b/ext/configuration.h index 970b97f212..4bdfb17192 100644 --- a/ext/configuration.h +++ b/ext/configuration.h @@ -168,6 +168,7 @@ enum ddtrace_sampling_rules_format { CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE_INJECT, "datadog,tracecontext") \ CONFIG(SET_LOWERCASE, DD_TRACE_PROPAGATION_STYLE, "datadog,tracecontext", \ .env_config_fallback = ddtrace_conf_otel_propagators) \ + CONFIG(BOOL, DD_TRACE_IGNORE_AGENT_SAMPLING_RATES, "false", .ini_change = zai_config_system_ini_change) \ CONFIG(SET, DD_TRACE_TRACED_INTERNAL_FUNCTIONS, "") \ CONFIG(INT, DD_TRACE_AGENT_TIMEOUT, DD_CFG_EXPSTR(DD_TRACE_AGENT_TIMEOUT_VAL), \ .ini_change = zai_config_system_ini_change) \ diff --git a/ext/ddtrace.c b/ext/ddtrace.c index e256d1aeae..bf583eff36 100644 --- a/ext/ddtrace.c +++ b/ext/ddtrace.c @@ -1568,7 +1568,7 @@ static void dd_initialize_request(void) { // Things that should only run on the first RINIT after each minit. pthread_once(&dd_rinit_once_control, dd_rinit_once); - if (!DDTRACE_G(agent_config_reader)) { + if (!DDTRACE_G(agent_config_reader) && !get_global_DD_TRACE_IGNORE_AGENT_SAMPLING_RATES()) { if (get_global_DD_TRACE_SIDECAR_TRACE_SENDER()) { if (ddtrace_endpoint) { DDTRACE_G(agent_config_reader) = ddog_agent_remote_config_reader_for_endpoint(ddtrace_endpoint); @@ -2304,7 +2304,7 @@ void dd_internal_handle_fork(void) { } ddtrace_seed_prng(); ddtrace_generate_runtime_id(); - ddtrace_reset_sidecar_globals(); + ddtrace_reset_sidecar(); if (!get_DD_TRACE_FORKED_PROCESS()) { ddtrace_disable_tracing_in_current_request(); } diff --git a/ext/live_debugger.c b/ext/live_debugger.c index 194640cfe4..2788860910 100644 --- a/ext/live_debugger.c +++ b/ext/live_debugger.c @@ -104,6 +104,7 @@ typedef struct { typedef struct { ddog_Probe probe; + bool removed; zend_string *function; zend_string *scope; zend_string *file; @@ -150,6 +151,7 @@ static int64_t dd_init_live_debugger_probe(const ddog_Probe *probe, dd_probe_def def->file = NULL; def->function = NULL; def->scope = NULL; + def->removed = false; const ddog_ProbeTarget *target = &probe->target; if (target->type_name.len) { @@ -267,7 +269,7 @@ static void dd_submit_probe_eval_error_snapshot(const ddog_Probe *probe, ddog_Ve static void dd_span_decoration_end(zend_ulong invocation, zend_execute_data *execute_data, zval *retval, void *auxiliary, void *dynamic) { dd_probe_def *def = auxiliary; ddtrace_span_data *span = ddtrace_active_span(); - if (!span) { + if (!span || def->removed) { return; } UNUSED(invocation, dynamic); @@ -423,6 +425,17 @@ static void dd_log_probe_end(zend_ulong invocation, zend_execute_data *execute_d return; } + if (def->parent.removed) { + if (dyn->payload) { + ddog_drop_debugger_payload(dyn->payload); + zend_string_release(dyn->service); + if (dyn->capture_arena) { + zend_arena_destroy(dyn->capture_arena); + } + } + return; + } + if (def->parent.probe.evaluate_at == DDOG_EVALUATE_AT_EXIT && !dd_log_probe_eval_condition(def, execute_data, retval)) { return; } @@ -490,7 +503,7 @@ static int64_t dd_set_log_probe(const ddog_Probe *probe, const ddog_MaybeShmLimi static void dd_metric_probe_end(zend_ulong invocation, zend_execute_data *execute_data, zval *retval, void *auxiliary, void *dynamic) { dd_probe_def *def = auxiliary; UNUSED(invocation, dynamic); - if (dd_probe_file_mismatch(def, execute_data)) { + if (def->removed || dd_probe_file_mismatch(def, execute_data)) { return; } @@ -584,6 +597,7 @@ static void dd_remove_live_debugger_probe(int64_t id) { if ((def = zend_hash_index_find_ptr(&DDTRACE_G(active_rc_hooks), (zend_ulong)id))) { zend_string *scope = def->scope ? zend_string_copy(def->scope) : NULL; zend_string *func = def->function ? zend_string_copy(def->function) : NULL; + def->removed = true; zai_hook_remove( def->scope ? (zai_str)ZAI_STR_FROM_ZSTR(def->scope) : (zai_str)ZAI_STR_EMPTY, def->function ? (zai_str)ZAI_STR_FROM_ZSTR(def->function) : (zai_str)ZAI_STR_EMPTY, diff --git a/ext/sidecar.c b/ext/sidecar.c index 7ec14b28e9..263ed7bd2b 100644 --- a/ext/sidecar.c +++ b/ext/sidecar.c @@ -36,7 +36,17 @@ static void ddtrace_set_resettable_sidecar_globals(void) { ddtrace_sidecar_instance_id = ddog_sidecar_instanceId_build(session_id, runtime_id); } -ddog_SidecarTransport *dd_sidecar_connection_factory(void) { +static inline void dd_set_endpoint_test_token(ddog_Endpoint *endpoint) { + if (zai_config_is_initialized()) { + if (ZSTR_LEN(get_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) { + ddog_endpoint_set_test_token(endpoint, dd_zend_string_to_CharSlice(get_DD_TRACE_AGENT_TEST_SESSION_TOKEN())); + } + } else if (ZSTR_LEN(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) { + ddog_endpoint_set_test_token(endpoint, dd_zend_string_to_CharSlice(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())); + } +} + +static ddog_SidecarTransport *dd_sidecar_connection_factory_ex(bool is_fork) { // Should not happen, unless the agent url is malformed if (!ddtrace_endpoint) { return NULL; @@ -51,9 +61,7 @@ ddog_SidecarTransport *dd_sidecar_connection_factory(void) { free(dogstatsd_url); } - if (ZSTR_LEN(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) { - ddog_endpoint_set_test_token(dogstatsd_endpoint, dd_zend_string_to_CharSlice(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())); - } + dd_set_endpoint_test_token(dogstatsd_endpoint); #ifdef _WIN32 DDOG_PHP_FUNCTION = (const uint8_t *)zend_hash_func; @@ -87,7 +95,8 @@ ddog_SidecarTransport *dd_sidecar_connection_factory(void) { DDTRACE_REMOTE_CONFIG_PRODUCTS.ptr, DDTRACE_REMOTE_CONFIG_PRODUCTS.len, DDTRACE_REMOTE_CONFIG_CAPABILITIES.ptr, - DDTRACE_REMOTE_CONFIG_CAPABILITIES.len); + DDTRACE_REMOTE_CONFIG_CAPABILITIES.len, + is_fork); ddog_endpoint_drop(dogstatsd_endpoint); @@ -98,6 +107,10 @@ ddog_SidecarTransport *dd_sidecar_connection_factory(void) { return sidecar_transport; } +ddog_SidecarTransport *dd_sidecar_connection_factory(void) { + return dd_sidecar_connection_factory_ex(false); +} + bool ddtrace_sidecar_maybe_enable_appsec(bool *appsec_features, bool *appsec_config) { *appsec_features = false; *appsec_config = false; @@ -157,11 +170,22 @@ void ddtrace_sidecar_shutdown(void) { } } -void ddtrace_reset_sidecar_globals(void) { +void ddtrace_reset_sidecar(void) { if (ddtrace_sidecar_instance_id) { ddog_sidecar_instanceId_drop(ddtrace_sidecar_instance_id); ddtrace_set_resettable_sidecar_globals(); } + + if (ddtrace_sidecar) { + ddog_sidecar_transport_drop(ddtrace_sidecar); + ddtrace_sidecar = dd_sidecar_connection_factory_ex(true); + if (!ddtrace_sidecar && ddtrace_endpoint) { // Something went wrong + ddog_endpoint_drop(ddtrace_endpoint); + ddtrace_endpoint = NULL; + } else { + ddtrace_sidecar_submit_root_span_data(); + } + } } ddog_Endpoint *ddtrace_sidecar_agent_endpoint(void) { @@ -178,9 +202,8 @@ ddog_Endpoint *ddtrace_sidecar_agent_endpoint(void) { free(agent_url); } - - if (agent_endpoint && ZSTR_LEN(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())) { - ddog_endpoint_set_test_token(agent_endpoint, dd_zend_string_to_CharSlice(get_global_DD_TRACE_AGENT_TEST_SESSION_TOKEN())); + if (agent_endpoint) { + dd_set_endpoint_test_token(agent_endpoint); } return agent_endpoint; @@ -431,6 +454,7 @@ void ddtrace_sidecar_rshutdown(void) { bool ddtrace_alter_test_session_token(zval *old_value, zval *new_value, zend_string *new_str) { UNUSED(old_value, new_str); if (ddtrace_sidecar) { + ddog_endpoint_set_test_token(ddtrace_endpoint, dd_zend_string_to_CharSlice(Z_STR_P(new_value))); ddog_CharSlice session_id = (ddog_CharSlice) {.ptr = (char *) dd_sidecar_formatted_session_id, .len = sizeof(dd_sidecar_formatted_session_id)}; ddtrace_ffi_try("Failed updating test session token", ddog_sidecar_set_test_session_token(&ddtrace_sidecar, session_id, dd_zend_string_to_CharSlice(Z_STR_P(new_value)))); diff --git a/ext/sidecar.h b/ext/sidecar.h index 25e5d0d4e1..8ad7d3ed7b 100644 --- a/ext/sidecar.h +++ b/ext/sidecar.h @@ -12,7 +12,7 @@ void ddtrace_sidecar_setup(bool appsec_features, bool appsec_config); bool ddtrace_sidecar_maybe_enable_appsec(bool *appsec_features, bool *appsec_config); void ddtrace_sidecar_ensure_active(void); void ddtrace_sidecar_shutdown(void); -void ddtrace_reset_sidecar_globals(void); +void ddtrace_reset_sidecar(void); void ddtrace_sidecar_submit_root_span_data(void); void ddtrace_sidecar_push_tag(ddog_Vec_Tag *vec, ddog_CharSlice key, ddog_CharSlice value); void ddtrace_sidecar_push_tags(ddog_Vec_Tag *vec, zval *tags); diff --git a/libdatadog b/libdatadog index 82cb3464c6..7a481f89ed 160000 --- a/libdatadog +++ b/libdatadog @@ -1 +1 @@ -Subproject commit 82cb3464c68387eb47a57ec9b19ea80f7732d366 +Subproject commit 7a481f89ed9a2d0ba473f4e946a3e68d6c8d3a97 diff --git a/tests/Common/CLITestCase.php b/tests/Common/CLITestCase.php index 646e16ea92..822eda0aca 100644 --- a/tests/Common/CLITestCase.php +++ b/tests/Common/CLITestCase.php @@ -92,9 +92,6 @@ public function executeCommand($arguments = '', $overrideEnvs = []) $arguments = escapeshellarg($arguments); $commandToExecute = "$envs " . PHP_BINARY . " $inis $script $arguments"; `$commandToExecute`; - if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { - \dd_trace_synchronous_flush(); - } } /** diff --git a/tests/Common/TracerTestTrait.php b/tests/Common/TracerTestTrait.php index 3390ad9468..4cff90bca1 100644 --- a/tests/Common/TracerTestTrait.php +++ b/tests/Common/TracerTestTrait.php @@ -3,6 +3,8 @@ namespace DDTrace\Tests\Common; use DDTrace\GlobalTracer; +use DDTrace\HookData; +use DDTrace\SpanData; use DDTrace\Tests\DebugTransport; use DDTrace\Tests\Frameworks\Util\Request\GetSpec; use DDTrace\Tests\Frameworks\Util\Request\RequestSpec; @@ -106,7 +108,7 @@ public function sendTracesToTestAgent($traces) curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // Set the headers // Execute the cURL session - $response = curl_exec($curl); + $response = self::curlWithoutSpan($curl); // Close the cURL session curl_close($curl); @@ -135,6 +137,15 @@ public function inRootSpan($fn, $tracer = null) return $this->flushAndGetTraces(); } + public static function curlWithoutSpan($curl) + { + $limit = ini_get("datadog.trace.spans_limit"); + ini_set("datadog.trace.spans_limit", 0); + $ret = curl_exec($curl); + ini_set("datadog.trace.spans_limit", $limit); + return $ret; + } + /** * @param $fn * @param null $tracer @@ -186,7 +197,7 @@ public function inWebServer($fn, $rootPath, $envs = [], $inis = [], &$curlInfo = $curl = curl_init('http://127.0.0.1:' . self::$webserverPort . $request->getPath()); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, $request->getHeaders()); - $response = curl_exec($curl); + $response = self::curlWithoutSpan($curl); if (\is_array($curlInfo)) { $curlInfo = \array_merge($curlInfo, \curl_getinfo($curl)); } @@ -269,7 +280,17 @@ public function executeCli($scriptPath, $customEnvs = [], $customInis = [], $arg $commandToExecute = "$envs " . PHP_BINARY . " $inis $script $arguments"; $output = []; $exitCode = 0; + $createHook = \DDTrace\install_hook('DDTrace\Integrations\Exec\ExecIntegration::createSpan', function (HookData $hook) { + $hook->disableJitInlining(); + $hook->suppressCall(); + $hook->overrideReturnValue(new SpanData); + }); + $finishHook = \DDTrace\install_hook('DDTrace\Integrations\Exec\ExecIntegration::finishSpanRestoreStack', function (HookData $hook) { + $hook->suppressCall(); + }); exec($commandToExecute . ' 2>&1', $output, $exitCode); + \DDTrace\remove_hook($createHook); + \DDTrace\remove_hook($finishHook); $ret = $withOutput ? implode("\n", $output) : null; if (!$skipSyncFlush && \dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { \dd_trace_synchronous_flush(); @@ -284,7 +305,7 @@ public function resetRequestDumper() { $curl = curl_init(self::$agentRequestDumperUrl . '/clear-dumped-data'); curl_setopt($curl, CURLOPT_HTTPHEADER, ['x-datadog-test-session-token: ' . ini_get("datadog.trace.agent_test_session_token")]); - curl_exec($curl); + self::curlWithoutSpan($curl); } /** @@ -297,7 +318,7 @@ public function resetRequestDumper() * @return array[] * @throws Exception */ - public function tracesFromWebRequest($fn, $tracer = null, callable $until = null) + public function tracesFromWebRequest($fn, $tracer = null, $until = null) { self::putEnv('DD_TRACE_SHUTDOWN_TIMEOUT=666666'); // Arbitrarily high value to avoid flakiness self::putEnv('DD_TRACE_AGENT_RETRIES=3'); @@ -316,10 +337,6 @@ public function tracesFromWebRequest($fn, $tracer = null, callable $until = null self::putEnv('DD_TRACE_SHUTDOWN_TIMEOUT'); self::putEnv('DD_TRACE_AGENT_RETRIES'); - if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { - \dd_trace_synchronous_flush(); - } - return $this->parseTracesFromDumpedData($until); } @@ -384,7 +401,7 @@ private function parseRawDumpedSpans($rawSpans) * @return array * @throws \Exception */ - private function parseTracesFromDumpedData(callable $until = null, $throw = false) + private function parseTracesFromDumpedData($until = null, $throw = false) { $loaded = $this->retrieveDumpedTraceData($until, $throw); if (!$loaded) { @@ -401,18 +418,24 @@ private function parseTracesFromDumpedData(callable $until = null, $throw = fals $dumps = array_merge($dumps, $this->parseRawDumpedTraces(json_decode($dump['body'], true))); } } + } else { + $uniqueRequest = $loaded[0]; - return $dumps; - } - - $uniqueRequest = $loaded[0]; + if (!isset($uniqueRequest['body'])) { + return []; + } - if (!isset($uniqueRequest['body'])) { - return []; + $rawTraces = json_decode($uniqueRequest['body'], true); + $dumps = $this->parseRawDumpedTraces($rawTraces); } - $rawTraces = json_decode($uniqueRequest['body'], true); - return $this->parseRawDumpedTraces($rawTraces); + // Ensure stable sorting; sort order isn't guaranteed with sidecar trace sender + // Sorting by end of root span + usort($dumps, function ($a, $b) { + return $a[0]["start"] + $a[0]["duration"] <=> $b[0]["start"] + $b[0]["duration"]; + }); + + return $dumps; } public function parseMultipleRequestsFromDumpedData() @@ -437,21 +460,24 @@ public function parseMultipleRequestsFromDumpedData() /** * Returns the raw response body, if any, or null otherwise. + * @param callable|null $until */ - public function retrieveDumpedData(callable $until = null, $throw = false) + public function retrieveDumpedData($until = null, $throw = false) { return $this->retrieveAnyDumpedData($until, $throw); } /** * Returns the raw response body, if any, or null otherwise. + * @param callable|null $until */ - public function retrieveDumpedMetrics(callable $until = null, $throw = false) + public function retrieveDumpedMetrics($until = null, $throw = false) { return $this->retrieveAnyDumpedData($until, $throw, true); } - public function retrieveAnyDumpedData(callable $until = null, $throw, $metrics = false) { + /** @param callable|null $until */ + public function retrieveAnyDumpedData($until, $throw, $metrics = false) { $until = $until ?? $this->untilFirstTraceRequest(); $allResponses = []; @@ -460,11 +486,15 @@ public function retrieveAnyDumpedData(callable $until = null, $throw, $metrics = // and actually sent. While we should find a smart way to tackle this, for now we do it quick and dirty, in a // for loop. for ($attemptNumber = 1; $attemptNumber <= 50; $attemptNumber++) { + if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { + \dd_trace_synchronous_flush(); + } + $curl = curl_init(self::$agentRequestDumperUrl . '/replay' . ($metrics ? '-metrics' : '')); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, ['x-datadog-test-session-token: ' . ini_get("datadog.trace.agent_test_session_token")]); // Retrieving data - $response = curl_exec($curl); + $response = self::curlWithoutSpan($curl); if (!$response) { // PHP-FPM requests are much slower in the container // Temporary workaround until we get a proper test runner @@ -493,7 +523,8 @@ public function retrieveAnyDumpedData(callable $until = null, $throw, $metrics = return $allResponses; } - public function retrieveDumpedTraceData(callable $until = null, $throw = false) + /** @param callable|null $until */ + public function retrieveDumpedTraceData($until = null, $throw = false) { return array_values(array_filter($this->retrieveDumpedData($until, $throw), function ($request) { // Filter telemetry requests diff --git a/tests/Integrations/AMQP/V2/AMQPTest.php b/tests/Integrations/AMQP/V2/AMQPTest.php index 02ea0e18f6..ad5d6e18ad 100644 --- a/tests/Integrations/AMQP/V2/AMQPTest.php +++ b/tests/Integrations/AMQP/V2/AMQPTest.php @@ -913,7 +913,7 @@ public function testDistributedTracing() foreach ($receiveTraces as $receiveTrace) { // Spans: connect -> queue_declare -> basic_consume & basic_consume_ok -> basic_deliver - if ($receiveTrace[0]["name"] == "amqp.basic.deliver") { + if ($receiveTrace[0]["name"] == "amqp.basic.deliver" && isset($receiveTrace[0]["parent_id"])) { $basicDeliverSpan = $receiveTrace[0]; break; } diff --git a/tests/Integrations/Curl/CurlIntegrationTest.php b/tests/Integrations/Curl/CurlIntegrationTest.php index 84b4613b16..7c286aaaf2 100644 --- a/tests/Integrations/Curl/CurlIntegrationTest.php +++ b/tests/Integrations/Curl/CurlIntegrationTest.php @@ -603,7 +603,7 @@ function ($execute) { $this->assertFlameGraph($traces, [ SpanAssertion::build('web.request', 'top_level_app', 'web', 'GET /curl_in_web_request.php') ->withExistingTagsNames(['http.method', 'http.url', 'http.status_code']) - ->withExactMetrics(['_sampling_priority_v1' => 1, 'process_id' => getmypid()]) + ->withExactMetrics(['_sampling_priority_v1' => 1, '_dd.agent_psr' => 1, 'process_id' => getmypid()]) ->withChildren([ SpanAssertion::build('curl_exec', 'curl', 'http', 'http://httpbin_integration/status/?') ->withExactTags([ diff --git a/tests/Integrations/DeferredLoading/index.php b/tests/Integrations/DeferredLoading/index.php index 11767cb556..f62acd3542 100644 --- a/tests/Integrations/DeferredLoading/index.php +++ b/tests/Integrations/DeferredLoading/index.php @@ -2,6 +2,8 @@ require __DIR__ . '/vendor/autoload.php'; +error_reporting(E_ALL & ~E_DEPRECATED); + // This script HAS to invoke at least two integrations via deferred integration loading mechanism. // PDO diff --git a/tests/Integrations/Logs/LaminasLogV2/LaminasLogV2Test.php b/tests/Integrations/Logs/LaminasLogV2/LaminasLogV2Test.php index bfb5963137..7ccd90cc1d 100644 --- a/tests/Integrations/Logs/LaminasLogV2/LaminasLogV2Test.php +++ b/tests/Integrations/Logs/LaminasLogV2/LaminasLogV2Test.php @@ -26,6 +26,9 @@ protected function getLogger($jsonFormatter = false) $writer = new Stream(static::logFile()); if ($jsonFormatter) { + if (!class_exists(Json::class)) { + $this->markTestSkipped("LaminasLog v2.7+ have an explicit PHP version support range. 2.6 gets automatically installed on PHP 8.4. But Json requires v2.10+. Skipping."); + } $writer->setFormatter(new Json()); } diff --git a/tests/Integrations/PCNTL/PCNTLTest.php b/tests/Integrations/PCNTL/PCNTLTest.php index 3df2bc579d..d03d0c0399 100644 --- a/tests/Integrations/PCNTL/PCNTLTest.php +++ b/tests/Integrations/PCNTL/PCNTLTest.php @@ -7,12 +7,17 @@ final class PCNTLTest extends IntegrationTestCase { - private static $acceptable_test_execution_time = 2; + private static $acceptable_test_execution_time; protected function ddSetUp() { if (!\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { self::$acceptable_test_execution_time = 1.4; + } elseif (time() < 1743515423) { + // We'll revisit it once we move off circleci. Relaxing the time check until 2025-04-01. + self::$acceptable_test_execution_time = 4; + } else { + self::$acceptable_test_execution_time = 2.5; } $this->resetRequestDumper(); @@ -41,47 +46,6 @@ public function testDoesNoHangAtShutdownWhenDisabled($scriptPath) $this->assertLessThan(self::$acceptable_test_execution_time, $end - $start); } - /** - * @dataProvider dataProviderAllScripts - */ - public function testDoesNoHangAtShutdownWhenEnabled($scriptPath) - { - if (extension_loaded('xdebug')) { - $this->markTestSkipped('xdebug is enabled, which causes the tracer to slow down dramatically.'); - } - - $start = \microtime(true); - $this->executeCli( - $scriptPath, - [ - 'DD_TRACE_CLI_ENABLED' => 'true', - 'DD_TRACE_SHUTDOWN_TIMEOUT' => 5000, - ], - [], - '', - false, - true - ); - $end = \microtime(true); - $this->assertLessThan(self::$acceptable_test_execution_time, $end - $start); - if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { - \dd_trace_synchronous_flush(); - } - } - - public function dataProviderAllScripts() - { - return [ - [__DIR__ . '/scripts/synthetic.php'], - [__DIR__ . '/scripts/short-running.php'], - [__DIR__ . '/scripts/short-running-multiple.php'], - [__DIR__ . '/scripts/short-running-multiple-nested.php'], - [__DIR__ . '/scripts/long-running-autoflush.php'], - [__DIR__ . '/scripts/long-running-manual-flush.php'], - [__DIR__ . '/scripts/access-tracer-after-fork.php'], - ]; - } - public function testCliShortRunningTracingWhenEnabled() { list($requests) = $this->inCli( @@ -96,21 +60,26 @@ public function testCliShortRunningTracingWhenEnabled() $this->untilNumberOfTraces(2) ); - $this->assertCount(2, $requests); - $this->assertFlameGraph([$requests[1]], [ - SpanAssertion::exists('synthetic.php')->withChildren([ - SpanAssertion::exists('pcntl_fork'), - ]), - ]); + try { + $this->assertFlameGraph([$requests[1]], [ + SpanAssertion::exists('synthetic.php')->withChildren([ + SpanAssertion::exists('pcntl_fork'), + ]), + ]); - $this->assertFlameGraph([$requests[0]], [ - SpanAssertion::exists('synthetic.php'), - ]); + $this->assertFlameGraph([$requests[0]], [ + SpanAssertion::exists('synthetic.php'), + ]); - $childSpan = $requests[0][0]; - $parentSpan = $requests[1][1]; - $this->assertSame($childSpan["trace_id"], $parentSpan["trace_id"]); - $this->assertSame($childSpan["parent_id"], $parentSpan["span_id"]); + $childSpan = $requests[0][0]; + $parentSpan = $requests[1][1]; + $this->assertSame($childSpan["trace_id"], $parentSpan["trace_id"]); + $this->assertSame($childSpan["parent_id"], $parentSpan["span_id"]); + } catch (\Exception $e) { + echo "Raw requests:\n"; + var_dump($requests); + throw $e; + } } public function testAccessingTracerAfterForkIsUnproblematic() @@ -319,4 +288,45 @@ public function testCliLongRunningMultipleForksManualFlush() ]); } } + + /** + * @dataProvider dataProviderAllScripts + */ + public function testDoesNoHangAtShutdownWhenEnabled($scriptPath) + { + if (extension_loaded('xdebug')) { + $this->markTestSkipped('xdebug is enabled, which causes the tracer to slow down dramatically.'); + } + + $start = \microtime(true); + $this->executeCli( + $scriptPath, + [ + 'DD_TRACE_CLI_ENABLED' => 'true', + 'DD_TRACE_SHUTDOWN_TIMEOUT' => 5000, + ], + [], + '', + false, + true + ); + $end = \microtime(true); + $this->assertLessThan(self::$acceptable_test_execution_time, $end - $start); + if (\dd_trace_env_config("DD_TRACE_SIDECAR_TRACE_SENDER")) { + \dd_trace_synchronous_flush(); + } + } + + public function dataProviderAllScripts() + { + return [ + [__DIR__ . '/scripts/synthetic.php'], + [__DIR__ . '/scripts/short-running.php'], + [__DIR__ . '/scripts/short-running-multiple.php'], + [__DIR__ . '/scripts/short-running-multiple-nested.php'], + [__DIR__ . '/scripts/long-running-autoflush.php'], + [__DIR__ . '/scripts/long-running-manual-flush.php'], + [__DIR__ . '/scripts/access-tracer-after-fork.php'], + ]; + } } diff --git a/tests/Integrations/PDO/PDOTest.php b/tests/Integrations/PDO/PDOTest.php index 690acb8f01..60096fdcfa 100644 --- a/tests/Integrations/PDO/PDOTest.php +++ b/tests/Integrations/PDO/PDOTest.php @@ -720,13 +720,7 @@ private function ensureActiveQueriesErrorCanHappen() $pdo = $this->pdoInstance($opts); $this->isolateTracer(function () use ($pdo) { - $pdo->beginTransaction(); - $stmt = $pdo->prepare("INSERT INTO tests (name) VALUES (?)"); - - for ($i = 0; $i < 1000; $i++) { - $stmt->execute(['Jerry']); - } - $pdo->commit(); + $pdo->query("INSERT INTO tests (name) VALUES " . str_repeat("('Jerry'), ", 999) . "('Jerry')"); }); return $pdo; } diff --git a/tests/Integrations/Swoole/CommonScenariosTest.php b/tests/Integrations/Swoole/CommonScenariosTest.php index ca88a43c18..0ee801e45d 100644 --- a/tests/Integrations/Swoole/CommonScenariosTest.php +++ b/tests/Integrations/Swoole/CommonScenariosTest.php @@ -95,7 +95,7 @@ public function provideSpecs() 'http.method' => 'GET', 'http.url' => 'http://localhost/error?key=value&', 'http.status_code' => '500', - 'error.stack' => "#0 [internal function]: {closure}()\n#1 {main}", + 'error.stack' => (PHP_VERSION_ID >= 80400 ? "#0 [internal function]: {closure:" . dirname(__DIR__, 2) . "/Frameworks/Swoole/index.php:9}()" : "#0 [internal function]: {closure}()") . "\n#1 {main}", Tag::SPAN_KIND => 'server', Tag::COMPONENT => 'swoole' ])->setError('Exception', 'Uncaught Exception: Error page'), diff --git a/tests/OpenTelemetry/composer-1.json b/tests/OpenTelemetry/composer-1.json index 3cd307c3b1..f968bafcf6 100644 --- a/tests/OpenTelemetry/composer-1.json +++ b/tests/OpenTelemetry/composer-1.json @@ -1,9 +1,9 @@ { "name": "datadog/dd-trace-tests", "require": { - "open-telemetry/sdk": "1.0.*", - "open-telemetry/extension-propagator-b3": "1.0.*", - "open-telemetry/opentelemetry-logger-monolog": "1.0.*" + "open-telemetry/sdk": "1.0.*||1.1.*", + "open-telemetry/extension-propagator-b3": "1.0.*||1.1.*", + "open-telemetry/opentelemetry-logger-monolog": "1.0.*||1.1.*" }, "minimum-stability": "stable" } diff --git a/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt b/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt index 0dc5715bf3..1293e47be7 100644 --- a/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt +++ b/tests/ext/background-sender/agent_headers_unix_domain_socket.phpt @@ -20,7 +20,7 @@ include __DIR__ . '/../includes/request_replayer.inc'; $rr = new RequestReplayer(); $rr->replayRequest(); // clear -RequestReplayer::launchUnixProxy(str_replace("unix://", "", getenv("DD_TRACE_AGENT_URL"))); +$proxy = RequestReplayer::launchUnixProxy(str_replace("unix://", "", getenv("DD_TRACE_AGENT_URL"))); \DDTrace\start_span(); \DDTrace\close_span(); diff --git a/tests/ext/background-sender/agent_sampling.phpt b/tests/ext/background-sender/agent_sampling.phpt index 2896404e3f..2e277539fb 100644 --- a/tests/ext/background-sender/agent_sampling.phpt +++ b/tests/ext/background-sender/agent_sampling.phpt @@ -10,6 +10,7 @@ DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 DD_TRACE_SIDECAR_TRACE_SENDER=0 +DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=0 --INI-- datadog.trace.agent_test_session_token=background-sender/agent_sampling --FILE-- diff --git a/tests/ext/background-sender/agent_sampling_sidecar.phpt b/tests/ext/background-sender/agent_sampling_sidecar.phpt index e33c298f11..45746c7e7b 100644 --- a/tests/ext/background-sender/agent_sampling_sidecar.phpt +++ b/tests/ext/background-sender/agent_sampling_sidecar.phpt @@ -11,6 +11,7 @@ DD_TRACE_AGENT_FLUSH_INTERVAL=333 DD_TRACE_GENERATE_ROOT_SPAN=0 DD_INSTRUMENTATION_TELEMETRY_ENABLED=0 DD_TRACE_SIDECAR_TRACE_SENDER=1 +DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=0 --INI-- datadog.trace.agent_test_session_token=background-sender/agent_sampling_sidecar --FILE-- diff --git a/tests/ext/background-sender/default_unix_domain_socket_agent.phpt b/tests/ext/background-sender/default_unix_domain_socket_agent.phpt index 397ca8d519..2a73a7fb5d 100644 --- a/tests/ext/background-sender/default_unix_domain_socket_agent.phpt +++ b/tests/ext/background-sender/default_unix_domain_socket_agent.phpt @@ -16,7 +16,7 @@ if (file_exists("/var/run/datadog/apm.socket")) { unlink("/var/run/datadog/apm.socket"); } -RequestReplayer::launchUnixProxy("/var/run/datadog/apm.socket"); +$proxy = RequestReplayer::launchUnixProxy("/var/run/datadog/apm.socket"); $logs = dd_get_startup_logs([], ['DD_TRACE_LOG_LEVEL' => 'error,startup=info']); diff --git a/tests/ext/crashtracker_segfault.phpt b/tests/ext/crashtracker_segfault.phpt index 5e4aae80d9..06e2c8c6aa 100644 --- a/tests/ext/crashtracker_segfault.phpt +++ b/tests/ext/crashtracker_segfault.phpt @@ -52,10 +52,11 @@ $rr->waitForRequest(function ($request) { --EXPECTF-- %A{ "message": { - "additional_stacktraces": [], +%A "files": { %A }, + "incomplete": false, "metadata": { "library_name": "dd-trace-php", "library_version": "%s", @@ -67,13 +68,12 @@ $rr->waitForRequest(function ($request) { "os_info": { %A }, - "span_ids": [], - "tags": [], - "trace_ids": [] + "timestamp": "%s", + "uuid": "%s" }, "level": "ERROR", "count": 1, "stack_trace": "%s", - "tags": "%ssigname:SIGSEGV%s", + "tags": "%ssi_signo_human_readable:SIGSEGV%S", "is_sensitive": true }%A diff --git a/tests/ext/dogstatsd/metrics_uds.inc b/tests/ext/dogstatsd/metrics_uds.inc index 32050fdc35..072daec7cc 100644 --- a/tests/ext/dogstatsd/metrics_uds.inc +++ b/tests/ext/dogstatsd/metrics_uds.inc @@ -1,5 +1,7 @@ proc = $proc; + } + + public function __destruct() { + proc_terminate($this->proc, 9); + } +} + class RequestReplayer { /** @@ -130,24 +141,26 @@ class RequestReplayer ignore_user_abort(true); /* prevent bailout... */ $server = stream_socket_server("unix://' . $socketPath . '"); print "1\n"; /* ready marker */ -if (!$client = stream_socket_accept($server, 5)) { - return; -} -$replayer = stream_socket_client("request-replayer:80"); -$all = $read = [$client, $replayer]; -foreach ($read as $fp) stream_set_blocking($fp, false); -while (stream_select($read, $w, $e, null)) { - $data = fread($fp = reset($read), 4096); - if ($data == "") { - return; +while ($client = stream_socket_accept($server, 5)) { + file_put_contents("/tmp/unix-proxy-' . basename($socketPath) . '", "connected\n", FILE_APPEND); + $replayer = stream_socket_client("request-replayer:80"); + $all = $read = [$client, $replayer]; + foreach ($read as $fp) stream_set_blocking($fp, false); + while (stream_select($read, $w, $e, null)) { + $data = fread($fp = reset($read), 4096); + if ($data == "") { + file_put_contents("/tmp/unix-proxy-' . basename($socketPath) . '", "end\n", FILE_APPEND); + break; + } + file_put_contents("/tmp/unix-proxy-' . basename($socketPath) . '", "$data\n", FILE_APPEND); + fwrite($fp == $replayer ? $client : $replayer, $data); + $read = $all; } - fwrite($fp == $replayer ? $client : $replayer, $data); - $read = $all; } '); - static $unix_proxy_process_reference; - $unix_proxy_process_reference = popen(PHP_BINARY . " -r '$code'", 'r'); - fread($unix_proxy_process_reference, 1); // ready + $proc = proc_open(PHP_BINARY . " -r '$code'", [STDIN, ["pipe", "w"], STDERR], $pipes); + fread($pipes[1], 1); // ready + return new ProxyContainer($proc); } } diff --git a/tests/ext/remote_config/dynamic_config_auto_update.phpt b/tests/ext/remote_config/dynamic_config_auto_update.phpt index c63911af57..64a3d6d0b5 100644 --- a/tests/ext/remote_config/dynamic_config_auto_update.phpt +++ b/tests/ext/remote_config/dynamic_config_auto_update.phpt @@ -23,13 +23,13 @@ $path = put_dynamic_config_file([ "log_injection_enabled" => true, ]); -usleep(500000); +usleep(getenv("USE_ZEND_ALLOC") === "0" ? 2000000 : 500000); var_dump(ini_get("datadog.logs_injection")); del_rc_file($path); -usleep(500000); +usleep(getenv("USE_ZEND_ALLOC") === "0" ? 2000000 : 500000); var_dump(ini_get("datadog.logs_injection")); diff --git a/tests/ext/remote_config/dynamic_config_update.phpt b/tests/ext/remote_config/dynamic_config_update.phpt index 2f29a0a026..449539147e 100644 --- a/tests/ext/remote_config/dynamic_config_update.phpt +++ b/tests/ext/remote_config/dynamic_config_update.phpt @@ -44,7 +44,7 @@ put_dynamic_config_file([ // submit span data \DDTrace\start_span(); -usleep(500000); +usleep(getenv("USE_ZEND_ALLOC") === "0" ? 2000000 : 500000); var_dump(ini_get("datadog.trace.sample_rate")); $tags = explode(",", ini_get("datadog.trace.header_tags")); diff --git a/tests/ext/root_span_url_as_resource_names.phpt b/tests/ext/root_span_url_as_resource_names.phpt index 4097014c5e..cc63e51e50 100644 --- a/tests/ext/root_span_url_as_resource_names.phpt +++ b/tests/ext/root_span_url_as_resource_names.phpt @@ -1,6 +1,5 @@ --TEST-- root span with DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED ---SKIPIF-- --ENV-- DD_TRACE_GENERATE_ROOT_SPAN=0 DD_TRACE_URL_AS_RESOURCE_NAMES_ENABLED=1 @@ -10,8 +9,6 @@ SERVER_NAME=localhost:8888 HTTP_HOST=localhost:9999 SCRIPT_NAME=/foo.php REQUEST_URI=/foo?with_to_be_stripped?query_string -QUERY_STRING=with_to_be_stripped?query_string -METHOD=GET --GET-- foo=bar --FILE-- diff --git a/tests/ext/single-span_sampling/check-sample-rate.phpt b/tests/ext/single-span_sampling/check-sample-rate.phpt index 130e317fd2..569ff40bc7 100644 --- a/tests/ext/single-span_sampling/check-sample-rate.phpt +++ b/tests/ext/single-span_sampling/check-sample-rate.phpt @@ -5,8 +5,8 @@ Check sample rate is in effect --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_SAMPLE_RATE=0 -DD_SPAN_SAMPLING_RULES=[{"sample_rate":0.5,"max_per_second":10}] -DD_TRACE_DEBUG_PRNG_SEED=30 +DD_SPAN_SAMPLING_RULES=[{"sample_rate":0.5,"max_per_second":3}] +DD_TRACE_DEBUG_PRNG_SEED=23 DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- --EXPECT-- First span: rule_rate=0.5 -15 dropped out of 27 -10 dropped out of 10 -22st span: rule_rate=0.5 +3 dropped out of 7 +3 dropped out of 3 +11th span: rule_rate=0.5 diff --git a/tests/ext/single-span_sampling/limited-single-span.phpt b/tests/ext/single-span_sampling/limited-single-span.phpt index 8ce5d712dc..fae3630103 100644 --- a/tests/ext/single-span_sampling/limited-single-span.phpt +++ b/tests/ext/single-span_sampling/limited-single-span.phpt @@ -5,31 +5,31 @@ Test max_per_second single span limiting --ENV-- DD_TRACE_AUTO_FLUSH_ENABLED=0 DD_TRACE_SAMPLE_RATE=0 -DD_SPAN_SAMPLING_RULES=[{"sample_rate":1,"max_per_second":10}] +DD_SPAN_SAMPLING_RULES=[{"sample_rate":1,"max_per_second":3}] DD_TRACE_GENERATE_ROOT_SPAN=0 --FILE-- --EXPECT-- -mechanism after 10: 8 -sampling present after 30: bool(false) +mechanism after 3: 8 +sampling present after 12: bool(false) diff --git a/tests/ext/telemetry/config.phpt b/tests/ext/telemetry/config.phpt index 06465c8cb8..16370f2142 100644 --- a/tests/ext/telemetry/config.phpt +++ b/tests/ext/telemetry/config.phpt @@ -14,6 +14,7 @@ DD_INSTRUMENTATION_TELEMETRY_ENABLED=1 DD_AGENT_HOST= DD_AUTOLOAD_NO_COMPILE= DD_TRACE_GIT_METADATA_ENABLED=0 +DD_TRACE_IGNORE_AGENT_SAMPLING_RATES=1 --INI-- datadog.trace.agent_url="file://{PWD}/config-telemetry.out" --FILE-- @@ -73,13 +74,20 @@ Array ) [2] => Array + ( + [name] => trace.ignore_agent_sampling_rates + [value] => 1 + [origin] => EnvVar + ) + + [3] => Array ( [name] => trace.generate_root_span [value] => 0 [origin] => EnvVar ) - [3] => Array + [4] => Array ( [name] => trace.git_metadata_enabled [value] => 0 diff --git a/tests/internal-api-stress-test.php b/tests/internal-api-stress-test.php index c28cfed506..6a8466a819 100644 --- a/tests/internal-api-stress-test.php +++ b/tests/internal-api-stress-test.php @@ -116,9 +116,14 @@ function ($hook = null) { return $garbage; } +$minFunctionArgs = []; + function call_function(ReflectionFunction $function) { - $i = PHP_VERSION_ID >= 80100 ? $function->getNumberOfRequiredParameters() : 0; + global $minFunctionArgs; + print "Executing: {$function->name}\n"; + + $i = PHP_VERSION_ID >= 80100 ? $function->getNumberOfRequiredParameters() : ($minFunctionArgs[$function->name] ?? 0); $invocations = $i == 0 ? [[]] : []; for (; $i < $function->getNumberOfParameters(); ++$i) { foreach ($invocations as $invocation) { @@ -130,10 +135,16 @@ function call_function(ReflectionFunction $function) } } - foreach ($invocations as $invocation) { + foreach ($invocations as &$invocation) { try { $function->invokeArgs($invocation); } catch (ArgumentCountError $e) { + $minFunctionArgs[$function->name] = $argc = count($invocation); + foreach ($invocations as $k => $cur) { + if (count($cur) <= $argc) { + unset($invocations[$k]); + } + } } catch (TypeError $e) { } } diff --git a/zend_abstract_interface/config/config.h b/zend_abstract_interface/config/config.h index 88f500dcd9..accbbb3988 100644 --- a/zend_abstract_interface/config/config.h +++ b/zend_abstract_interface/config/config.h @@ -101,4 +101,6 @@ bool zai_config_get_id_by_name(zai_str name, zai_config_id *id); // Adds name to name<->id mapping. Id may be present multiple times. void zai_config_register_config_id(zai_config_name *name, zai_config_id id); +bool zai_config_is_initialized(void); + #endif // ZAI_CONFIG_H