diff --git a/agent/fw_drupal8.c b/agent/fw_drupal8.c index 32976c64a..c59b21e0b 100644 --- a/agent/fw_drupal8.c +++ b/agent/fw_drupal8.c @@ -18,6 +18,7 @@ #include "util_logging.h" #include "util_memory.h" #include "util_strings.h" +#include "zend_types.h" #define PHP_PACKAGE_NAME "drupal/core" @@ -66,8 +67,7 @@ NR_PHP_WRAPPER(nr_drupal_exception) { if (NR_SUCCESS != nr_php_error_record_exception(NRPRG(txn), exception, priority, true, - NULL, - &NRPRG(exception_filters))) { + NULL, &NRPRG(exception_filters))) { nrl_verbosedebug(NRL_TXN, "Drupal: unable to record exception"); } @@ -134,12 +134,12 @@ static void nr_drupal8_add_method_callback(const zend_class_entry* ce, #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ && !defined OVERWRITE_ZEND_EXECUTE_DATA static void nr_drupal8_add_method_callback_before_after_clean( - const zend_class_entry* ce, - const char* method, - size_t method_len, - nrspecialfn_t before_callback, - nrspecialfn_t after_callback, - nrspecialfn_t clean_callback) { + const zend_class_entry* ce, + const char* method, + size_t method_len, + nrspecialfn_t before_callback, + nrspecialfn_t after_callback, + nrspecialfn_t clean_callback) { zend_function* function = NULL; if (NULL == ce) { @@ -164,13 +164,13 @@ static void nr_drupal8_add_method_callback_before_after_clean( nr_php_class_entry_name(ce), NRSAFELEN(method_len), method); nr_php_wrap_user_function_before_after_clean( - class_method, nr_strlen(class_method), - before_callback, after_callback, clean_callback); + class_method, nr_strlen(class_method), before_callback, after_callback, + clean_callback); nr_free(class_method); } } -#endif // OAPI +#endif // OAPI /* * Purpose : Check if the given function or method is in the current call @@ -394,6 +394,27 @@ NR_PHP_WRAPPER(nr_drupal8_wrap_view_execute) { } NR_PHP_WRAPPER_END +NR_PHP_WRAPPER(nr_drupal_hook_attribute_construct) { + (void)wraprec; + zval* hook = NULL; + zval* method = NULL; + zval* module = NULL; + + NR_PHP_WRAPPER_REQUIRE_FRAMEWORK(NR_FW_DRUPAL8); + hook = nr_php_arg_get(1, NR_EXECUTE_ORIG_ARGS); + method = nr_php_arg_get(2, NR_EXECUTE_ORIG_ARGS); + module = nr_php_arg_get(3, NR_EXECUTE_ORIG_ARGS); + + nrl_always("%s: hook= %s, method= %s, module= %s", __FUNCTION__, + Z_STRVAL_P(hook), Z_STRVAL_P(method), Z_STRVAL_P(module)); + + NR_PHP_WRAPPER_CALL; + nr_php_arg_release(&hook); + nr_php_arg_release(&method); + nr_php_arg_release(&module); +} +NR_PHP_WRAPPER_END + /* * Purpose : Iterator function to walk over an array of module names * implementing a particular hook and instrument those hooks. @@ -501,8 +522,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with_callback) { #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ && !defined OVERWRITE_ZEND_EXECUTE_DATA - zval* curr_hook - = (zval*)nr_stack_get_top(&NRPRG(drupal_invoke_all_hooks)); + zval* curr_hook = (zval*)nr_stack_get_top(&NRPRG(drupal_invoke_all_hooks)); if (UNEXPECTED(!nr_php_is_zval_non_empty_string(curr_hook))) { nrl_verbosedebug(NRL_FRAMEWORK, "%s: cannot extract hook name from global stack", @@ -515,7 +535,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with_callback) { nr_drupal_hook_instrument(Z_STRVAL_P(module), Z_STRLEN_P(module), NRPRG(drupal_invoke_all_hook), NRPRG(drupal_invoke_all_hook_len) TSRMLS_CC); -#endif // OAPI +#endif // OAPI leave: NR_PHP_WRAPPER_CALL; @@ -536,7 +556,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with) { || defined OVERWRITE_ZEND_EXECUTE_DATA char* prev_hook = NULL; int prev_hook_len; -#endif // not OAPI +#endif // not OAPI (void)wraprec; @@ -547,7 +567,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with) { #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ && !defined OVERWRITE_ZEND_EXECUTE_DATA nr_php_arg_release(&hook); -#endif // OAPI +#endif // OAPI goto leave; } @@ -561,7 +581,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with) { = nr_strndup(Z_STRVAL_P(hook), Z_STRLEN_P(hook)); NRPRG(drupal_invoke_all_hook_len) = Z_STRLEN_P(hook); NRPRG(check_cufa) = true; -#endif // OAPI +#endif // OAPI callback = nr_php_arg_get(2, NR_EXECUTE_ORIG_ARGS TSRMLS_CC); /* This instrumentation will fail if callback has already been wrapped @@ -581,14 +601,14 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with) { if (NULL == NRPRG(drupal_invoke_all_hook)) { NRPRG(check_cufa) = false; } -#endif // not OAPI +#endif // not OAPI -leave: ; +leave:; #if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO \ || defined OVERWRITE_ZEND_EXECUTE_DATA /* for OAPI, the _after callback handles this free */ nr_php_arg_release(&hook); -#endif // not OAPI +#endif // not OAPI } NR_PHP_WRAPPER_END @@ -605,7 +625,7 @@ NR_PHP_WRAPPER(nr_drupal94_invoke_all_with_clean) { nr_drupal_invoke_all_hook_stacks_pop(); } NR_PHP_WRAPPER_END -#endif // OAPI +#endif // OAPI /* * Purpose : Wrap the invoke() method of the module handler instance in use. @@ -642,10 +662,8 @@ NR_PHP_WRAPPER(nr_drupal8_module_handler) { #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ && !defined OVERWRITE_ZEND_EXECUTE_DATA nr_drupal8_add_method_callback_before_after_clean( - ce, NR_PSTR("invokeallwith"), - nr_drupal94_invoke_all_with, - nr_drupal94_invoke_all_with_after, - nr_drupal94_invoke_all_with_clean); + ce, NR_PSTR("invokeallwith"), nr_drupal94_invoke_all_with, + nr_drupal94_invoke_all_with_after, nr_drupal94_invoke_all_with_clean); #else nr_drupal8_add_method_callback(ce, NR_PSTR("invokeallwith"), nr_drupal94_invoke_all_with TSRMLS_CC); @@ -807,6 +825,9 @@ void nr_drupal8_enable(TSRMLS_D) { nr_drupal_exception); // clang-format on + nr_php_wrap_user_function( + NR_PSTR("Drupal\\Core\\Hook\\Attribute\\Hook::__construct"), + nr_drupal_hook_attribute_construct); /* * The drupal_modules config setting controls instrumentation of modules, * hooks, and views.