From 2a3c331bf8e6bd4e3a1f746408a6d46176faefe4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 4 Jan 2024 06:02:12 +0100 Subject: [PATCH] Avoid resolving unresolved functions and classes This only may pose problems with DDTrace\Trace attributes. In theory having the hook installed twice should not pose problems, but adding a hook to an unresolved class is at the very least not a supported scenario. Checking for the classes being actually linked. This only affects PHP 8.0 and PHP 8.1. Signed-off-by: Bob Weinand --- tests/ext/traced_attribute.phpt | 2 +- tests/ext/traced_attribute_delayed.phpt | 57 +++++++++++++++++++ .../interceptor/php8/resolver_pre-8_2.c | 15 ++++- 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 tests/ext/traced_attribute_delayed.phpt diff --git a/tests/ext/traced_attribute.phpt b/tests/ext/traced_attribute.phpt index 762478b90f..1e1d713b27 100644 --- a/tests/ext/traced_attribute.phpt +++ b/tests/ext/traced_attribute.phpt @@ -1,5 +1,5 @@ --TEST-- -Set DDTrace\start_span() properties +Test tracing via attributes --SKIPIF-- --ENV-- diff --git a/tests/ext/traced_attribute_delayed.phpt b/tests/ext/traced_attribute_delayed.phpt new file mode 100644 index 0000000000..e70adc220f --- /dev/null +++ b/tests/ext/traced_attribute_delayed.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test delayed resolution of tracing attributes +--SKIPIF-- + +--ENV-- +DD_TRACE_GENERATE_ROOT_SPAN=0 +--FILE-- + +--EXPECTF-- +int(1) +int(1) +spans(\DDTrace\SpanData) (2) { + simpleclass (traced_attribute_delayed.php, simpleclass, cli) + _dd.p.dm => -0 + _dd.p.tid => %s + simplefunc (traced_attribute_delayed.php, simplefunc, cli) + _dd.p.dm => -0 + _dd.p.tid => %s +} diff --git a/zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c b/zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c index 4491947356..cb725c5cd5 100644 --- a/zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c +++ b/zend_abstract_interface/interceptor/php8/resolver_pre-8_2.c @@ -13,8 +13,10 @@ static void zai_interceptor_add_new_entries(HashPosition classpos, HashPosition for (zend_class_entry *ce; (ce = zend_hash_get_current_data_ptr_ex(CG(class_table), &classpos)); zend_hash_move_forward_ex(CG(class_table), &classpos)) { - zend_hash_get_current_key_ex(CG(class_table), &lcname, &index, &classpos); - zai_hook_resolve_class(ce, lcname); + if (ce->ce_flags & ZEND_ACC_LINKED) { + zend_hash_get_current_key_ex(CG(class_table), &lcname, &index, &classpos); + zai_hook_resolve_class(ce, lcname); + } } zend_hash_move_forward_ex(CG(function_table), &funcpos); // move past previous end @@ -22,7 +24,14 @@ static void zai_interceptor_add_new_entries(HashPosition classpos, HashPosition (func = zend_hash_get_current_data_ptr_ex(CG(function_table), &funcpos)); zend_hash_move_forward_ex(CG(function_table), &funcpos)) { zend_hash_get_current_key_ex(CG(function_table), &lcname, &index, &funcpos); - zai_hook_resolve_function(func, lcname); +#if PHP_VERSION_ID < 80100 + // check for unlinked function: "rtd_key" (i.e. lcname) starts with NUL-byte + // On PHP 8.1+ these are attached to the op_array instead and not present in CG(function_table). + if (ZSTR_VAL(lcname)[0]) +#endif + { + zai_hook_resolve_function(func, lcname); + } } }