From d53cf9fde7115136223f154f87328e669e6698cf Mon Sep 17 00:00:00 2001 From: Sammy Powers Date: Thu, 19 Nov 2020 09:25:35 -0800 Subject: [PATCH] Fix distributed tracing on PHP 8 The curl extension API was upgraded from a resource to an object in php/php-src#5402. --- Makefile | 3 + bridge/{php5.php => curl_inject.php} | 0 bridge/dd_init.php | 4 +- config.m4 | 1 - ext/php8/ddtrace.c | 4 +- ext/php8/ddtrace.h | 42 -- ext/php8/distributed_tracing.c | 7 - ext/php8/distributed_tracing.h | 11 - ext/php8/engine_api.c | 15 +- ext/php8/engine_api.h | 2 +- ext/php8/handlers_curl.c | 464 ++++++------------ ext/php8/handlers_internal.c | 2 + ext/php8/handlers_internal.h | 1 + ext/php8/span.h | 3 - package.xml | 6 +- .../Integrations/Curl/CurlIntegrationTest.php | 22 +- .../ext/sandbox/distributed_tracing_curl.phpt | 2 +- .../distributed_tracing_curl_copy_handle.phpt | 2 +- ...ted_tracing_curl_existing_headers_001.phpt | 2 +- ...ted_tracing_curl_existing_headers_002.phpt | 2 +- .../distributed_tracing_curl_missing_fn.phpt | 8 +- .../distributed_tracing_curl_sandboxed.phpt | 2 +- 22 files changed, 200 insertions(+), 405 deletions(-) rename bridge/{php5.php => curl_inject.php} (100%) delete mode 100644 ext/php8/distributed_tracing.c delete mode 100644 ext/php8/distributed_tracing.h diff --git a/Makefile b/Makefile index 22dea61b1a..de80e2e303 100644 --- a/Makefile +++ b/Makefile @@ -476,8 +476,11 @@ TEST_WEB_74 := \ test_opentracing_10 TEST_INTEGRATIONS_80 := \ + test_integrations_curl \ test_integrations_mysqli \ test_integrations_pdo \ + test_integrations_guzzle5 \ + test_integrations_guzzle6 \ test_integrations_predis1 TEST_WEB_80 := \ diff --git a/bridge/php5.php b/bridge/curl_inject.php similarity index 100% rename from bridge/php5.php rename to bridge/curl_inject.php diff --git a/bridge/dd_init.php b/bridge/dd_init.php index 12e2be6c65..9ede5166db 100755 --- a/bridge/dd_init.php +++ b/bridge/dd_init.php @@ -60,8 +60,8 @@ function_exists('dd_trace_internal_fn') && \dd_trace_internal_fn('ddtrace_reload // Required classes and functions require __DIR__ . '/autoload.php'; -if (\PHP_MAJOR_VERSION === 5) { - require __DIR__ . '/php5.php'; +if (\PHP_MAJOR_VERSION === 8 || \PHP_MAJOR_VERSION === 5) { + require __DIR__ . '/curl_inject.php'; } // Optional classes and functions diff --git a/config.m4 b/config.m4 index 6478d423af..d1411512a2 100644 --- a/config.m4 +++ b/config.m4 @@ -162,7 +162,6 @@ if test "$PHP_DDTRACE" != "no"; then ext/php8/configuration_php_iface.c \ ext/php8/ddtrace_string.c \ ext/php8/dispatch.c \ - ext/php8/distributed_tracing.c \ ext/php8/dogstatsd_client.c \ ext/php8/engine_api.c \ ext/php8/engine_hooks.c \ diff --git a/ext/php8/ddtrace.c b/ext/php8/ddtrace.c index b9ce413369..013634f96c 100644 --- a/ext/php8/ddtrace.c +++ b/ext/php8/ddtrace.c @@ -36,7 +36,6 @@ #include "ddtrace.h" #include "ddtrace_string.h" #include "dispatch.h" -#include "distributed_tracing.h" #include "dogstatsd_client.h" #include "engine_hooks.h" #include "excluded_modules.h" @@ -420,10 +419,10 @@ static PHP_RINIT_FUNCTION(ddtrace) { dd_request_init_hook_rinit(TSRMLS_C); } + ddtrace_internal_handlers_rinit(); ddtrace_engine_hooks_rinit(TSRMLS_C); ddtrace_bgs_log_rinit(PG(error_log)); ddtrace_dispatch_init(TSRMLS_C); - ddtrace_distributed_tracing_rinit(TSRMLS_C); DDTRACE_G(disable_in_current_request) = 0; ddtrace_dogstatsd_client_rinit(TSRMLS_C); @@ -458,7 +457,6 @@ static PHP_RSHUTDOWN_FUNCTION(ddtrace) { ddtrace_internal_handlers_rshutdown(); ddtrace_dogstatsd_client_rshutdown(TSRMLS_C); - ddtrace_distributed_tracing_rshutdown(TSRMLS_C); ddtrace_dispatch_destroy(TSRMLS_C); ddtrace_free_span_id_stack(TSRMLS_C); ddtrace_free_span_stacks(TSRMLS_C); diff --git a/ext/php8/ddtrace.h b/ext/php8/ddtrace.h index 6afc471767..17441d2420 100644 --- a/ext/php8/ddtrace.h +++ b/ext/php8/ddtrace.h @@ -15,14 +15,12 @@ extern zend_class_entry *ddtrace_ce_fatal_error; typedef struct ddtrace_span_ids_t ddtrace_span_ids_t; typedef struct ddtrace_span_fci ddtrace_span_fci; -#if PHP_VERSION_ID >= 70000 zval *ddtrace_spandata_property_name(zval *spandata); zval *ddtrace_spandata_property_resource(zval *spandata); zval *ddtrace_spandata_property_service(zval *spandata); zval *ddtrace_spandata_property_type(zval *spandata); zval *ddtrace_spandata_property_meta(zval *spandata); zval *ddtrace_spandata_property_metrics(zval *spandata); -#endif BOOL_T ddtrace_tracer_is_limited(TSRMLS_D); @@ -45,25 +43,6 @@ ZEND_BEGIN_MODULE_GLOBALS(ddtrace) char *dogstatsd_port; char *dogstatsd_buffer; - // PHP 7 uses ZEND_TLS for these -#if PHP_VERSION_ID < 70000 - // Distributed tracing & curl - HashTable *dt_http_saved_curl_headers; - zend_bool back_up_http_headers; - - /* These ones are used for measuring the call stack depth so that we can - * emit a warning prior to encountering a stack overflow. - * - * A 16-bit call depth would allow us to count to 65,535, which is way more - * than necessary. An 8-bit depth would be inadequate (255). - */ - bool should_warn_call_depth; - uint16_t call_depth; - - // ext/curl's list entry resource type - int le_curl; -#endif - uint64_t trace_id; ddtrace_span_ids_t *span_ids_top; ddtrace_span_fci *open_spans_top; @@ -92,13 +71,7 @@ ZEND_END_MODULE_GLOBALS(ddtrace) * defines these macros without the comma in the definition site, so that it * exists at the usage site. */ -#if PHP_VERSION_ID < 70000 -#define DDTRACE_ARG_INFO_SIZE(arg_info) ((zend_uint)(sizeof(arg_info) / sizeof(struct _zend_arg_info) - 1)) -#elif PHP_VERSION_ID < 80100 #define DDTRACE_ARG_INFO_SIZE(arg_info) ((uint32_t)(sizeof(arg_info) / sizeof(struct _zend_internal_arg_info) - 1)) -#else -#error Check if ZEND_FENTRY has changed in PHP 8.1 and if we need to update the macros -#endif #define DDTRACE_FENTRY(zend_name, name, arg_info, flags) \ { #zend_name, name, arg_info, DDTRACE_ARG_INFO_SIZE(arg_info), flags } @@ -111,19 +84,4 @@ ZEND_END_MODULE_GLOBALS(ddtrace) #define DDTRACE_FALIAS(name, alias, arg_info) DDTRACE_RAW_FENTRY(#name, zif_##alias, arg_info, 0) #define DDTRACE_FE_END ZEND_FE_END -/* Currently used on PHP 5. After a zend_execute_ex has called the previous hook - * the execute_data cannot be trusted for some things, notably function_state. - * So we use this struct to back up the data. - */ -struct ddtrace_execute_data { - zval *This; - zend_class_entry *scope; - zend_function *fbc; - const zend_op *opline; - void **arguments; - zval *retval; - bool free_retval; -}; -typedef struct ddtrace_execute_data ddtrace_execute_data; - #endif // DDTRACE_H diff --git a/ext/php8/distributed_tracing.c b/ext/php8/distributed_tracing.c deleted file mode 100644 index c7f98a0307..0000000000 --- a/ext/php8/distributed_tracing.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "distributed_tracing.h" - -#include "compatibility.h" - -void ddtrace_distributed_tracing_rinit(TSRMLS_D) {} - -void ddtrace_distributed_tracing_rshutdown(TSRMLS_D) {} diff --git a/ext/php8/distributed_tracing.h b/ext/php8/distributed_tracing.h deleted file mode 100644 index 1152c09085..0000000000 --- a/ext/php8/distributed_tracing.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef DDTRACE_DISTRIBUTED_TRACING_H -#define DDTRACE_DISTRIBUTED_TRACING_H - -#include - -#include "compatibility.h" - -void ddtrace_distributed_tracing_rinit(TSRMLS_D); -void ddtrace_distributed_tracing_rshutdown(TSRMLS_D); - -#endif // DDTRACE_DISTRIBUTED_TRACING_H diff --git a/ext/php8/engine_api.c b/ext/php8/engine_api.c index 1cf6770dfa..10853ba2bd 100644 --- a/ext/php8/engine_api.c +++ b/ext/php8/engine_api.c @@ -79,7 +79,7 @@ ZEND_RESULT_CODE ddtrace_call_method(zend_object *obj, zend_class_entry *ce, zen } ZEND_RESULT_CODE ddtrace_call_function(zend_function **fn_proxy, const char *name, size_t name_len, zval *retval, - int argc, zval argv[]) { + int argc, ...) { zend_fcall_info fci = { .size = sizeof(zend_fcall_info), }; @@ -87,6 +87,11 @@ ZEND_RESULT_CODE ddtrace_call_function(zend_function **fn_proxy, const char *nam .function_handler = (fn_proxy && *fn_proxy) ? *fn_proxy : NULL, }; + va_list argv; + va_start(argv, argc); + zend_fcall_info_argv(&fci, (uint32_t)argc, &argv); + va_end(argv); + if (!fcc.function_handler) { // This avoids allocating a zend_string if fn_proxy is used zval fname = ddtrace_zval_stringl(name, name_len); @@ -111,12 +116,10 @@ ZEND_RESULT_CODE ddtrace_call_function(zend_function **fn_proxy, const char *nam // ZVAL_COPY_VALUE(&fci.function_name, fcc.function_handler->common.function_name); fci.retval = retval; - fci.params = argv; -#if PHP_VERSION_ID < 80000 - fci.no_separation = 0; // allow for by-ref args -#endif - fci.param_count = argc; ZEND_RESULT_CODE result = zend_call_function(&fci, &fcc); + + zend_fcall_info_args_clear(&fci, 1); + return result; } diff --git a/ext/php8/engine_api.h b/ext/php8/engine_api.h index d919922f16..3033933b1a 100644 --- a/ext/php8/engine_api.h +++ b/ext/php8/engine_api.h @@ -50,7 +50,7 @@ inline zval ddtrace_zval_undef(void) { ZEND_RESULT_CODE ddtrace_call_method(zend_object *obj, zend_class_entry *ce, zend_function **fn_proxy, const char *fname, size_t fname_len, zval *retval, int argc, zval *argv); ZEND_RESULT_CODE ddtrace_call_function(zend_function **fn_proxy, const char *name, size_t name_len, zval *retval, - int argc, zval argv[]); + int argc, ...); void ddtrace_write_property(zval *obj, const char *prop, size_t prop_len, zval *value); bool ddtrace_property_exists(zval *object, zval *property); diff --git a/ext/php8/handlers_curl.c b/ext/php8/handlers_curl.c index 9c29ec3472..f24f44c8c6 100644 --- a/ext/php8/handlers_curl.c +++ b/ext/php8/handlers_curl.c @@ -1,364 +1,209 @@ -#include #include +#include + +#include -#include "compat_string.h" #include "configuration.h" #include "engine_api.h" #include "engine_hooks.h" // for ddtrace_backup_error_handling #include "handlers_internal.h" +#include "logging.h" #include "span.h" -#ifndef ZVAL_COPY_DEREF -#define ZVAL_COPY_DEREF(z, v) \ - do { \ - zval *_z3 = (v); \ - if (Z_OPT_REFCOUNTED_P(_z3)) { \ - if (UNEXPECTED(Z_OPT_ISREF_P(_z3))) { \ - _z3 = Z_REFVAL_P(_z3); \ - if (Z_OPT_REFCOUNTED_P(_z3)) { \ - Z_ADDREF_P(_z3); \ - } \ - } else { \ - Z_ADDREF_P(_z3); \ - } \ - } \ - ZVAL_COPY_VALUE(z, _z3); \ - } while (0) -#endif - -bool _dd_ext_curl_loaded = false; // True global -- do not modify after startup - -/* "le_curl" is ext/curl's resource type. - * "le_curl" is what php_curl.h names this variable - */ -ZEND_TLS int le_curl = 0; - -/* Cache things we tend to use a few times */ -ZEND_TLS zval _dd_curl_httpheaders = {.u1.type_info = IS_UNDEF}; -ZEND_TLS zval _dd_format_curl_http_headers = {.u1.type_info = IS_UNDEF}; -ZEND_TLS zend_class_entry *_dd_ArrayKVStore_ce = NULL; -ZEND_TLS zend_class_entry *_dd_GlobalTracer_ce = NULL; -ZEND_TLS zend_class_entry *_dd_SpanContext_ce = NULL; -ZEND_TLS zend_function *_dd_ArrayKVStore_putForResource_fe = NULL; -ZEND_TLS zend_function *_dd_ArrayKVStore_getForResource_fe = NULL; -ZEND_TLS zend_function *_dd_ArrayKVStore_deleteResource_fe = NULL; -ZEND_TLS zend_function *_dd_GlobalTracer_get_fe = NULL; -ZEND_TLS zend_function *_dd_SpanContext_ctor = NULL; -ZEND_TLS bool _dd_curl_integration_loaded = false; - -static void (*_dd_curl_close_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; -static void (*_dd_curl_exec_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; -static void (*_dd_curl_copy_handle_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; -static void (*_dd_curl_init_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; -static void (*_dd_curl_setopt_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; -static void (*_dd_curl_setopt_array_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; - -// Should be run after request_init_hook is run *and* all the classes are loaded -static bool _dd_load_curl_integration(void) { - if (!get_dd_trace_sandbox_enabled() || DDTRACE_G(disable_in_current_request)) { - return false; - } - - if (_dd_curl_integration_loaded) { - return true; - } +// True global - only modify during MINIT/MSHUTDOWN +bool dd_ext_curl_loaded = false; +zend_long dd_const_curlopt_httpheader = 0; - _dd_ArrayKVStore_ce = ddtrace_lookup_ce(ZEND_STRL("DDTrace\\Util\\ArrayKVStore")); - _dd_GlobalTracer_ce = ddtrace_lookup_ce(ZEND_STRL("DDTrace\\GlobalTracer")); - _dd_SpanContext_ce = ddtrace_lookup_ce(ZEND_STRL("DDTrace\\SpanContext")); +ZEND_TLS HashTable *dd_headers = NULL; +ZEND_TLS bool dd_should_save_headers = true; +ZEND_TLS zend_function *dd_curl_inject_fn_proxy = NULL; - if (!_dd_ArrayKVStore_ce || !_dd_GlobalTracer_ce || !_dd_SpanContext_ce) { - return false; - } +static void (*dd_curl_close_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; +static void (*dd_curl_exec_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; +static void (*dd_curl_copy_handle_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; +static void (*dd_curl_init_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; +static void (*dd_curl_setopt_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; +static void (*dd_curl_setopt_array_handler)(INTERNAL_FUNCTION_PARAMETERS) = NULL; - zend_string *format_headers = zend_string_init(ZEND_STRL("DDTrace\\Format::CURL_HTTP_HEADERS"), 0); - zval *format_headers_zv = zend_get_constant_ex(format_headers, NULL, ZEND_FETCH_CLASS_SILENT); - zend_string_release(format_headers); - if (format_headers_zv) { - ZVAL_COPY(&_dd_format_curl_http_headers, format_headers_zv); - } else { +static bool dd_load_curl_integration(void) { + if (!dd_ext_curl_loaded || DDTRACE_G(disable_in_current_request)) { return false; } - - zend_string *curlopt_httpheader = zend_string_init(ZEND_STRL("CURLOPT_HTTPHEADER"), 0); - zval *curlopt_httpheader_zv = zend_get_constant_ex(curlopt_httpheader, NULL, ZEND_FETCH_CLASS_SILENT); - zend_string_release(curlopt_httpheader); - if (curlopt_httpheader_zv) { - ZVAL_COPY(&_dd_curl_httpheaders, curlopt_httpheader_zv); - } else { - return false; - } - - _dd_curl_integration_loaded = true; - return true; + return ddtrace_config_distributed_tracing_enabled(); } -static void _dd_ArrayKVStore_deleteResource(zval *ch) { - zval retval = ddtrace_zval_undef(); - zend_call_method_with_1_params(NULL, _dd_ArrayKVStore_ce, &_dd_ArrayKVStore_deleteResource_fe, "deleteresource", - &retval, ch); +static void dd_headers_dtor(void *headers) { + HashTable *ht = *((HashTable **)headers); + zend_hash_destroy(ht); + FREE_HASHTABLE(ht); } -static zval dd_ArrayKVStore_getForResource(zval *ch, zval *format, zval *value) { - zval retval = ddtrace_zval_null(), args[3] = {*ch, *format, *value}; - zend_function **fn_proxy = &_dd_ArrayKVStore_getForResource_fe; - ddtrace_call_method(NULL, _dd_ArrayKVStore_ce, fn_proxy, ZEND_STRL("getForResource"), &retval, 3, args); - return retval; -} +static void dd_ch_store_headers(zval *ch, HashTable *headers) { + if (!dd_headers) { + ALLOC_HASHTABLE(dd_headers); + zend_hash_init(dd_headers, 8, NULL, (dtor_func_t)dd_headers_dtor, 0); + } -static void _dd_ArrayKVStore_putForResource(zval *ch, zval *format, zval *value) { - zval retval = ddtrace_zval_undef(), args[3] = {*ch, *format, *value}; - zend_function **fn_proxy = &_dd_ArrayKVStore_putForResource_fe; - ddtrace_call_method(NULL, _dd_ArrayKVStore_ce, fn_proxy, ZEND_STRL("putForResource"), &retval, 3, args); - zval_ptr_dtor(&retval); -} + HashTable *new_headers; + ALLOC_HASHTABLE(new_headers); + zend_hash_init(new_headers, zend_hash_num_elements(headers), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(new_headers, headers, (copy_ctor_func_t)zval_add_ref); -ZEND_FUNCTION(ddtrace_curl_close) { - zval *ch; + zend_hash_index_update_ptr(dd_headers, Z_OBJ_HANDLE_P(ch), new_headers); +} - if (_dd_load_curl_integration() && - zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &ch) == SUCCESS) { - ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); - _dd_ArrayKVStore_deleteResource(ch); - ddtrace_sandbox_end(&backup); +static void dd_ch_delete_headers(zval *ch) { + if (dd_headers) { + zend_hash_index_del(dd_headers, Z_OBJ_HANDLE_P(ch)); } - - _dd_curl_close_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); } -ZEND_FUNCTION(ddtrace_curl_copy_handle) { - zval *ch1; - bool should_hook = _dd_load_curl_integration() && - zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &ch1) == SUCCESS; - _dd_curl_copy_handle_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); - - if (should_hook && Z_TYPE_P(return_value) == IS_RESOURCE && ddtrace_config_distributed_tracing_enabled()) { - ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); - zval default_headers, *ch2 = return_value; - array_init(&default_headers); - zval http_headers = dd_ArrayKVStore_getForResource(ch1, &_dd_format_curl_http_headers, &default_headers); - - if (Z_TYPE(http_headers) == IS_ARRAY) { - _dd_ArrayKVStore_putForResource(ch2, &_dd_format_curl_http_headers, &http_headers); +static void dd_ch_duplicate_headers(zval *ch_orig, zval *ch_new) { + if (dd_headers) { + HashTable *headers = zend_hash_index_find_ptr(dd_headers, Z_OBJ_HANDLE_P(ch_orig)); + if (headers) { + dd_ch_store_headers(ch_new, headers); } - - zval_ptr_dtor(&http_headers); - zval_ptr_dtor(&default_headers); - ddtrace_sandbox_end(&backup); } } -/* curl_exec {{{ */ -static ZEND_RESULT_CODE dd_span_context_new(zval *context, zval trace_id, zval span_id, zval parent_id, zval origin) { - if (object_init_ex(context, _dd_SpanContext_ce) == FAILURE) { - return FAILURE; +static void dd_init_headers_arg(zval *arg, zval *ch) { + HashTable *retval; + ALLOC_HASHTABLE(retval); + HashTable *headers = NULL; + + if (dd_headers) { + headers = zend_hash_index_find_ptr(dd_headers, Z_OBJ_HANDLE_P(ch)); + if (headers) { + size_t headers_count = zend_hash_num_elements(headers); + zend_hash_init(retval, headers_count, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(retval, headers, (copy_ctor_func_t)zval_add_ref); + } } - zval construct_args[3] = {trace_id, span_id, parent_id}; - - zval retval = ddtrace_zval_undef(); - ZEND_RESULT_CODE result = ddtrace_call_method(Z_OBJ_P(context), _dd_SpanContext_ce, &_dd_SpanContext_ctor, - ZEND_STRL("__construct"), &retval, 3, construct_args); - zval_ptr_dtor(&retval); - if (result == SUCCESS) { - if (Z_TYPE(origin) == IS_STRING) { - ddtrace_write_property(context, ZEND_STRL("origin"), &origin); - } + if (!headers) { + zend_hash_init(retval, 0, NULL, ZVAL_PTR_DTOR, 0); } - return result; + ZVAL_ARR(arg, retval); } -// headers will get modified! -static ZEND_RESULT_CODE dd_tracer_inject_helper(zval *headers, zval *format, ddtrace_span_t *span) { - zval tracer = ddtrace_zval_undef(); - // $tracer = \DDTrace\GlobalTracer::get(); - if (ddtrace_call_method(NULL, _dd_GlobalTracer_ce, &_dd_GlobalTracer_get_fe, ZEND_STRL("get"), &tracer, 0, NULL) == - FAILURE) { - return FAILURE; - } +static void dd_free_headers_arg(zval *arg) { zend_array_destroy(Z_ARRVAL_P(arg)); } - ZEND_RESULT_CODE result = FAILURE; +ZEND_FUNCTION(ddtrace_curl_close) { + zval *ch; - /* In limited tracing mode, we need to add the distributed trace headers - * even if we aren't making a new span for curl_exec. We also need "origin" - * which exists only on userland span contexts. For both these reasons we - * fetch the Tracer's active span. - */ - zval active_span = ddtrace_zval_undef(), active_context = ddtrace_zval_null(); - zval origin = ddtrace_zval_null(); - if (ddtrace_call_method(Z_OBJ(tracer), Z_OBJ(tracer)->ce, NULL, ZEND_STRL("getActiveSpan"), &active_span, 0, - NULL) != SUCCESS) { - goto cleanup_tracer; + if (dd_load_curl_integration() && + zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &ch, curl_ce) == SUCCESS) { + dd_ch_delete_headers(ch); } - if (Z_TYPE(active_span) == IS_OBJECT) { - if (ddtrace_call_method(Z_OBJ(active_span), Z_OBJ(active_span)->ce, NULL, ZEND_STRL("getContext"), - &active_context, 0, NULL) != SUCCESS) { - goto cleanup_active_span; - } else { - ddtrace_read_property(&origin, &active_context, ZEND_STRL("origin")); - } - } - - zval trace_id = ddtrace_zval_long(0); - zval span_id = ddtrace_zval_long(0); - zval parent_id = ddtrace_zval_long(0); - if (span) { - zval tmp = ddtrace_zval_long(span->trace_id); - ddtrace_convert_to_string(&trace_id, &tmp); - - tmp = ddtrace_zval_long(span->span_id); - ddtrace_convert_to_string(&span_id, &tmp); - - if (span->parent_id > 0) { - tmp = ddtrace_zval_long(span->parent_id); - ddtrace_convert_to_string(&parent_id, &tmp); - } - } else if (Z_TYPE(active_context) == IS_OBJECT) { - zend_object *obj = Z_OBJ(active_context); - zend_class_entry *ce = obj->ce; - ddtrace_call_method(obj, ce, NULL, ZEND_STRL("getTraceId"), &trace_id, 0, NULL); - ddtrace_call_method(obj, ce, NULL, ZEND_STRL("getSpanId"), &span_id, 0, NULL); - ddtrace_call_method(obj, ce, NULL, ZEND_STRL("getParentId"), &parent_id, 0, NULL); - } else { - goto cleanup_active_context; - } + dd_curl_close_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} - zval context = ddtrace_zval_undef(); - if (UNEXPECTED(dd_span_context_new(&context, trace_id, span_id, parent_id, origin) != SUCCESS)) { - goto cleanup_origin; - } +ZEND_FUNCTION(ddtrace_curl_copy_handle) { + zval *ch; - zval inject_args[3] = {context, *format, *headers}; - zval retval = ddtrace_zval_undef(); - // $tracer->inject($context, Format::CURL_HTTP_HEADERS, $httpHeaders); - result = ddtrace_call_method(Z_OBJ(tracer), Z_OBJ(tracer)->ce, NULL, ZEND_STRL("inject"), &retval, 3, inject_args); - if (EXPECTED(result == SUCCESS)) { - ZVAL_COPY_DEREF(headers, &inject_args[2]); - zval_ptr_dtor(&inject_args[2]); + if (!dd_load_curl_integration() || + zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &ch, curl_ce) == FAILURE) { + dd_curl_copy_handle_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + return; } - zval_ptr_dtor(&retval); - zval_ptr_dtor(&context); -cleanup_origin: - zval_ptr_dtor(&parent_id); - zval_ptr_dtor(&span_id); - zval_ptr_dtor(&trace_id); - zval_ptr_dtor(&origin); -cleanup_active_context: - zval_ptr_dtor(&active_context); -cleanup_active_span: - zval_ptr_dtor(&active_span); -cleanup_tracer: - zval_ptr_dtor(&tracer); - return result; -} + dd_curl_copy_handle_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); -// Assumes distributed tracing is enabled and curl_handle is valid; active_span may be null -static void dd_add_headers_to_curl_handle(zval *curl_handle, ddtrace_span_fci *active_span) { - ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); - zval default_headers; - array_init(&default_headers); - zval http_headers = dd_ArrayKVStore_getForResource(curl_handle, &_dd_format_curl_http_headers, &default_headers); - zval_ptr_dtor(&default_headers); - - if (EXPECTED(Z_TYPE(http_headers) == IS_ARRAY)) { - zval *format = &_dd_format_curl_http_headers; - if (dd_tracer_inject_helper(&http_headers, format, active_span ? &active_span->span : NULL) == SUCCESS) { - zval setopt_args[3] = {*curl_handle, _dd_curl_httpheaders, http_headers}; - zval retval = ddtrace_zval_undef(); - // todo: cache curl_setopt lookup - ddtrace_call_function(NULL, ZEND_STRL("curl_setopt"), &retval, 3, setopt_args); - zval_ptr_dtor(&retval); - } + if (Z_TYPE_P(return_value) == IS_OBJECT) { + dd_ch_duplicate_headers(ch, return_value); } - zval_ptr_dtor(&http_headers); - ddtrace_sandbox_end(&backup); } ZEND_FUNCTION(ddtrace_curl_exec) { zval *ch; - if (le_curl && _dd_load_curl_integration() && Z_TYPE(_dd_curl_httpheaders) == IS_LONG && - zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "r", &ch) == SUCCESS) { - void *resource = zend_fetch_resource(Z_RES_P(ch), NULL, le_curl); - if (resource && ddtrace_config_distributed_tracing_enabled()) { - dd_add_headers_to_curl_handle(ch, DDTRACE_G(open_spans_top)); + if (dd_load_curl_integration() && ddtrace_peek_span_id() != 0 && + zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "O", &ch, curl_ce) == SUCCESS) { + zend_string *inject_func = zend_string_init(ZEND_STRL("ddtrace\\bridge\\curl_inject_distributed_headers"), 0); + if (zend_hash_exists(EG(function_table), inject_func)) { + zend_function **fn_proxy = &dd_curl_inject_fn_proxy; + zval retval = {.u1.type_info = IS_UNDEF}; + + zval headers; + dd_init_headers_arg(&headers, ch); + + ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); + dd_should_save_headers = false; // Don't save our own HTTP headers + // Arg 0: CurlHandle $ch + // Arg 1: mixed $value (array of headers) + if (ddtrace_call_function(fn_proxy, ZSTR_VAL(inject_func), ZSTR_LEN(inject_func), &retval, 2, ch, + &headers) == SUCCESS) { + zval_ptr_dtor(&retval); + } else { + ddtrace_log_debug("Could not inject distributed tracing headers"); + } + dd_should_save_headers = true; + ddtrace_sandbox_end(&backup); + + dd_free_headers_arg(&headers); } + zend_string_release(inject_func); } - _dd_curl_exec_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + dd_curl_exec_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); } -/* }}} */ ZEND_FUNCTION(ddtrace_curl_init) { - _dd_curl_init_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + dd_curl_init_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); - if (Z_TYPE_P(return_value) == IS_RESOURCE) { - if (!le_curl) { - le_curl = Z_RES_TYPE_P(return_value); - } - if (_dd_load_curl_integration()) { - _dd_ArrayKVStore_deleteResource(return_value); - } + if (dd_load_curl_integration() && Z_TYPE_P(return_value) == IS_OBJECT) { + dd_ch_delete_headers(return_value); } } ZEND_FUNCTION(ddtrace_curl_setopt) { - zval *zid, *zvalue; + zval *ch, *zvalue; zend_long option; - if (!le_curl || !_dd_load_curl_integration() || - zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "rlz", &zid, &option, &zvalue) == FAILURE) { - _dd_curl_setopt_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + if (!dd_load_curl_integration() || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "Olz", &ch, + curl_ce, &option, &zvalue) == FAILURE) { + dd_curl_setopt_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); return; } - _dd_curl_setopt_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + dd_curl_setopt_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); - ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); - - bool call_succeeded = Z_TYPE_P(return_value) == IS_TRUE; - bool option_matches = Z_TYPE(_dd_curl_httpheaders) == IS_LONG && Z_LVAL(_dd_curl_httpheaders) == option; - if (call_succeeded && option_matches && ddtrace_config_distributed_tracing_enabled()) { - _dd_ArrayKVStore_putForResource(zid, &_dd_format_curl_http_headers, zvalue); + if (dd_should_save_headers && Z_TYPE_P(return_value) == IS_TRUE && dd_const_curlopt_httpheader == option && + Z_TYPE_P(zvalue) == IS_ARRAY) { + dd_ch_store_headers(ch, Z_ARRVAL_P(zvalue)); } - - ddtrace_sandbox_end(&backup); } ZEND_FUNCTION(ddtrace_curl_setopt_array) { - zval *zid, *arr; - - if (le_curl && _dd_load_curl_integration() && - zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "ra", &zid, &arr) == SUCCESS) { - ddtrace_sandbox_backup backup = ddtrace_sandbox_begin(); - - void *resource = zend_fetch_resource(Z_RES_P(zid), NULL, le_curl); - if (resource && ddtrace_config_distributed_tracing_enabled()) { - if (Z_TYPE(_dd_curl_httpheaders) == IS_LONG) { - zval *value = zend_hash_index_find(Z_ARR_P(arr), Z_LVAL(_dd_curl_httpheaders)); - if (value) { - _dd_ArrayKVStore_putForResource(zid, &_dd_format_curl_http_headers, value); - } - } - } + zval *ch, *arr; - ddtrace_sandbox_end(&backup); + if (!dd_load_curl_integration() || + zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "Oa", &ch, curl_ce, &arr) == FAILURE) { + dd_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + return; } - _dd_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + dd_curl_setopt_array_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); + + if (Z_TYPE_P(return_value) == IS_TRUE) { + zval *value = zend_hash_index_find(Z_ARRVAL_P(arr), dd_const_curlopt_httpheader); + if (value && Z_TYPE_P(value) == IS_ARRAY) { + dd_ch_store_headers(ch, Z_ARRVAL_P(value)); + } + } } -struct _dd_curl_handler { +struct dd_curl_handler { const char *name; size_t name_len; void (**old_handler)(INTERNAL_FUNCTION_PARAMETERS); void (*new_handler)(INTERNAL_FUNCTION_PARAMETERS); }; -typedef struct _dd_curl_handler _dd_curl_handler; +typedef struct dd_curl_handler dd_curl_handler; -static void _dd_install_handler(_dd_curl_handler handler) { +static void dd_install_handler(dd_curl_handler handler) { zend_function *old_handler; old_handler = zend_hash_str_find_ptr(CG(function_table), handler.name, handler.name_len); if (old_handler != NULL) { @@ -370,11 +215,21 @@ static void _dd_install_handler(_dd_curl_handler handler) { void ddtrace_curl_handlers_startup(void) { // if we cannot find ext/curl then do not instrument it zend_string *curl = zend_string_init(ZEND_STRL("curl"), 0); - _dd_ext_curl_loaded = zend_hash_exists(&module_registry, curl); + dd_ext_curl_loaded = zend_hash_exists(&module_registry, curl); zend_string_release(curl); - if (!_dd_ext_curl_loaded) { + if (!dd_ext_curl_loaded) { + return; + } + + zend_string *const_name = zend_string_init(ZEND_STRL("CURLOPT_HTTPHEADER"), 0); + zval *const_value = zend_get_constant_ex(const_name, NULL, ZEND_FETCH_CLASS_SILENT); + zend_string_release(const_name); + if (!const_value) { + // If this fails, something is really wrong + dd_ext_curl_loaded = false; return; } + dd_const_curlopt_httpheader = Z_LVAL_P(const_value); /* We hook into curl_exec twice: * - One that handles general dispatch so it will call the associated closure with curl_exec @@ -382,17 +237,17 @@ void ddtrace_curl_handlers_startup(void) { * The latter expects the former is already done because it needs a span id for the distributed tracing headers; * register them inside-out. */ - _dd_curl_handler handlers[] = { - {ZEND_STRL("curl_close"), &_dd_curl_close_handler, ZEND_FN(ddtrace_curl_close)}, - {ZEND_STRL("curl_copy_handle"), &_dd_curl_copy_handle_handler, ZEND_FN(ddtrace_curl_copy_handle)}, - {ZEND_STRL("curl_exec"), &_dd_curl_exec_handler, ZEND_FN(ddtrace_curl_exec)}, - {ZEND_STRL("curl_init"), &_dd_curl_init_handler, ZEND_FN(ddtrace_curl_init)}, - {ZEND_STRL("curl_setopt"), &_dd_curl_setopt_handler, ZEND_FN(ddtrace_curl_setopt)}, - {ZEND_STRL("curl_setopt_array"), &_dd_curl_setopt_array_handler, ZEND_FN(ddtrace_curl_setopt_array)}, + dd_curl_handler handlers[] = { + {ZEND_STRL("curl_close"), &dd_curl_close_handler, ZEND_FN(ddtrace_curl_close)}, + {ZEND_STRL("curl_copy_handle"), &dd_curl_copy_handle_handler, ZEND_FN(ddtrace_curl_copy_handle)}, + {ZEND_STRL("curl_exec"), &dd_curl_exec_handler, ZEND_FN(ddtrace_curl_exec)}, + {ZEND_STRL("curl_init"), &dd_curl_init_handler, ZEND_FN(ddtrace_curl_init)}, + {ZEND_STRL("curl_setopt"), &dd_curl_setopt_handler, ZEND_FN(ddtrace_curl_setopt)}, + {ZEND_STRL("curl_setopt_array"), &dd_curl_setopt_array_handler, ZEND_FN(ddtrace_curl_setopt_array)}, }; size_t handlers_len = sizeof handlers / sizeof handlers[0]; for (size_t i = 0; i < handlers_len; ++i) { - _dd_install_handler(handlers[i]); + dd_install_handler(handlers[i]); } if (ddtrace_resource != -1) { @@ -401,18 +256,17 @@ void ddtrace_curl_handlers_startup(void) { } } +void ddtrace_curl_handlers_rinit(void) { + dd_headers = NULL; + dd_should_save_headers = true; + dd_curl_inject_fn_proxy = NULL; +} + void ddtrace_curl_handlers_rshutdown(void) { - le_curl = 0; - zval_ptr_dtor(&_dd_format_curl_http_headers); - ZVAL_UNDEF(&_dd_curl_httpheaders); - ZVAL_UNDEF(&_dd_format_curl_http_headers); - _dd_ArrayKVStore_ce = NULL; - _dd_GlobalTracer_ce = NULL; - _dd_SpanContext_ce = NULL; - _dd_ArrayKVStore_putForResource_fe = NULL; - _dd_ArrayKVStore_getForResource_fe = NULL; - _dd_ArrayKVStore_deleteResource_fe = NULL; - _dd_GlobalTracer_get_fe = NULL; - _dd_SpanContext_ctor = NULL; - _dd_curl_integration_loaded = false; + if (dd_headers) { + zend_hash_destroy(dd_headers); + FREE_HASHTABLE(dd_headers); + dd_headers = NULL; + } + dd_curl_inject_fn_proxy = NULL; } diff --git a/ext/php8/handlers_internal.c b/ext/php8/handlers_internal.c index a39a2eae1d..dd0f6e93b8 100644 --- a/ext/php8/handlers_internal.c +++ b/ext/php8/handlers_internal.c @@ -91,6 +91,7 @@ void ddtrace_phpredis_handlers_startup(void); void ddtrace_mysqli_handlers_shutdown(void); void ddtrace_pdo_handlers_shutdown(void); +void ddtrace_curl_handlers_rinit(void); void ddtrace_curl_handlers_rshutdown(void); // Internal handlers use ddtrace_resource and only implement the sandbox API. @@ -138,4 +139,5 @@ void ddtrace_internal_handlers_shutdown(void) { ddtrace_pdo_handlers_shutdown(); } +void ddtrace_internal_handlers_rinit(void) { ddtrace_curl_handlers_rinit(); } void ddtrace_internal_handlers_rshutdown(void) { ddtrace_curl_handlers_rshutdown(); } diff --git a/ext/php8/handlers_internal.h b/ext/php8/handlers_internal.h index d36d6cbc0e..25c9b01550 100644 --- a/ext/php8/handlers_internal.h +++ b/ext/php8/handlers_internal.h @@ -11,6 +11,7 @@ void ddtrace_replace_internal_methods(ddtrace_string Class, size_t methods_len, void ddtrace_internal_handlers_startup(void); void ddtrace_internal_handlers_shutdown(void); +void ddtrace_internal_handlers_rinit(void); void ddtrace_internal_handlers_rshutdown(void); #endif // DDTRACE_HANDLERS_INTERNAL_H diff --git a/ext/php8/span.h b/ext/php8/span.h index a6a7c7a283..3f5d36d582 100644 --- a/ext/php8/span.h +++ b/ext/php8/span.h @@ -31,9 +31,6 @@ struct ddtrace_span_fci { zend_execute_data *execute_data; struct ddtrace_dispatch_t *dispatch; ddtrace_exception_t *exception; -#if PHP_VERSION_ID < 70000 - ddtrace_execute_data dd_execute_data; -#endif struct ddtrace_span_fci *next; ddtrace_span_t span; }; diff --git a/package.xml b/package.xml index c067dc32c4..928a888212 100644 --- a/package.xml +++ b/package.xml @@ -217,8 +217,6 @@ - - @@ -591,10 +589,10 @@ + - @@ -616,10 +614,10 @@ + - diff --git a/tests/Integrations/Curl/CurlIntegrationTest.php b/tests/Integrations/Curl/CurlIntegrationTest.php index f4c6174838..9ea2838ed3 100644 --- a/tests/Integrations/Curl/CurlIntegrationTest.php +++ b/tests/Integrations/Curl/CurlIntegrationTest.php @@ -284,14 +284,14 @@ public function testNonExistingHost() public function testKVStoreIsCleanedOnCurlClose() { - if (\PHP_MAJOR_VERSION === 5) { - $this->markTestSkipped("PHP 5 does not use ArrayKVStore"); + if (\PHP_MAJOR_VERSION === 5 || \PHP_MAJOR_VERSION === 8) { + self::markTestSkipped("PHP 5 & 8 do not use ArrayKVStore"); } $ch = curl_init(self::URL . '/status/200'); curl_setopt($ch, CURLOPT_HTTPHEADER, []); - $this->assertNotSame('default', ArrayKVStore::getForResource($ch, Format::CURL_HTTP_HEADERS, 'default')); + self::assertNotSame('default', ArrayKVStore::getForResource($ch, Format::CURL_HTTP_HEADERS, 'default')); curl_close($ch); - $this->assertSame('default', ArrayKVStore::getForResource($ch, Format::CURL_HTTP_HEADERS, 'default')); + self::assertSame('default', ArrayKVStore::getForResource($ch, Format::CURL_HTTP_HEADERS, 'default')); } public function testDistributedTracingIsPropagated() @@ -320,19 +320,19 @@ public function testDistributedTracingIsPropagated() $span->finish(); }); - $this->assertEquals( - PHP_MAJOR_VERSION === 5, + self::assertEquals( + PHP_MAJOR_VERSION === 5 || PHP_MAJOR_VERSION === 8, function_exists('DDTrace\\Bridge\\curl_inject_distributed_headers') ); // trace is: custom - $this->assertSame($traces[0][0]['trace_id'], (int) $found['headers']['X-Datadog-Trace-Id']); + self::assertSame($traces[0][0]['trace_id'], (int) $found['headers']['X-Datadog-Trace-Id']); // parent is: curl_exec - $this->assertSame($traces[0][1]['span_id'], (int) $found['headers']['X-Datadog-Parent-Id']); - $this->assertSame('1', $found['headers']['X-Datadog-Sampling-Priority']); - $this->assertSame($traces[0][0]['metrics']['_sampling_priority_v1'], PrioritySampling::AUTO_KEEP); + self::assertSame($traces[0][1]['span_id'], (int) $found['headers']['X-Datadog-Parent-Id']); + self::assertSame('1', $found['headers']['X-Datadog-Sampling-Priority']); + self::assertSame($traces[0][0]['metrics']['_sampling_priority_v1'], PrioritySampling::AUTO_KEEP); // existing headers are honored - $this->assertSame('preserved_value', $found['headers']['Honored']); + self::assertSame('preserved_value', $found['headers']['Honored']); } public function testOriginIsPropagatedAndSetsRootSpanTag() diff --git a/tests/ext/sandbox/distributed_tracing_curl.phpt b/tests/ext/sandbox/distributed_tracing_curl.phpt index 0ad8be4691..f83604abc7 100644 --- a/tests/ext/sandbox/distributed_tracing_curl.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl.phpt @@ -1,7 +1,7 @@ --TEST-- Distributed tracing headers propagate with curl_exec() --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI-- diff --git a/tests/ext/sandbox/distributed_tracing_curl_copy_handle.phpt b/tests/ext/sandbox/distributed_tracing_curl_copy_handle.phpt index d047b79022..21afedad23 100644 --- a/tests/ext/sandbox/distributed_tracing_curl_copy_handle.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl_copy_handle.phpt @@ -1,7 +1,7 @@ --TEST-- Distributed tracing headers propagate after curl_copy_handle() --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI-- diff --git a/tests/ext/sandbox/distributed_tracing_curl_existing_headers_001.phpt b/tests/ext/sandbox/distributed_tracing_curl_existing_headers_001.phpt index 7fb7b76037..24562d646a 100644 --- a/tests/ext/sandbox/distributed_tracing_curl_existing_headers_001.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl_existing_headers_001.phpt @@ -1,7 +1,7 @@ --TEST-- Distributed tracing headers propagate with existing headers set with curl_setopt() --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI-- diff --git a/tests/ext/sandbox/distributed_tracing_curl_existing_headers_002.phpt b/tests/ext/sandbox/distributed_tracing_curl_existing_headers_002.phpt index 83479cc0ff..fb0168c884 100644 --- a/tests/ext/sandbox/distributed_tracing_curl_existing_headers_002.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl_existing_headers_002.phpt @@ -1,7 +1,7 @@ --TEST-- Distributed tracing headers propagate with existing headers set with curl_setopt_array() --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI-- diff --git a/tests/ext/sandbox/distributed_tracing_curl_missing_fn.phpt b/tests/ext/sandbox/distributed_tracing_curl_missing_fn.phpt index 6463a1ac6f..975b459bcd 100644 --- a/tests/ext/sandbox/distributed_tracing_curl_missing_fn.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl_missing_fn.phpt @@ -1,7 +1,7 @@ --TEST-- If curl_inject_distributed_headers helper is missing, we don't sigsegv, right? --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI-- @@ -31,10 +31,10 @@ dt_dump_headers_from_httpbin($headers, [ ]); $spans = dd_trace_serialize_closed_spans(); -assert(isset($headers['x-datadog-parent-id'])); +var_dump(isset($headers['x-datadog-parent-id'])); echo 'Done.' . PHP_EOL; ?> ---EXPECTF-- -Warning: assert(): Assertion failed in %s on line %d +--EXPECT-- +bool(false) Done. diff --git a/tests/ext/sandbox/distributed_tracing_curl_sandboxed.phpt b/tests/ext/sandbox/distributed_tracing_curl_sandboxed.phpt index 720f94fa91..8892159d61 100644 --- a/tests/ext/sandbox/distributed_tracing_curl_sandboxed.phpt +++ b/tests/ext/sandbox/distributed_tracing_curl_sandboxed.phpt @@ -1,7 +1,7 @@ --TEST-- Calls to curl_inject_distributed_headers() are sandboxed --SKIPIF-- -= 70000) die('skip: PHP 7 not supported'); ?> += 70000 && PHP_VERSION_ID < 80000) die('skip: PHP 7 not supported'); ?> --INI--