Skip to content

Commit

Permalink
fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
ZNeumann authored and lavarou committed Jul 31, 2024
1 parent 0e35b01 commit 6a46a5d
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 75 deletions.
124 changes: 81 additions & 43 deletions agent/php_observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,55 @@ static zend_observer_fcall_handlers nr_php_fcall_register_handlers(
handlers.end = nr_php_observer_fcall_end;
return handlers;
}

#else

static zend_observer_fcall_begin_handler nr_php_observer_determine_begin_handler(nruserfn_t* wraprec) {
zend_observer_fcall_begin_handler begin = NULL;

if (NULL == wraprec) {
if (NRINI(tt_detail)) {
begin = nr_php_observer_fcall_begin;
} else {
begin = nr_php_observer_empty_fcall_begin;
}
} else {
if (wraprec->special_instrumentation_before) {
begin = (zend_observer_fcall_begin_handler)wraprec->special_instrumentation_before;
} else if (wraprec->is_names_wt_simple) {
begin = nr_php_observer_fcall_begin_name_transaction;
} else if (wraprec->is_transient) {
begin = nr_php_observer_fcall_begin;
} else {
begin = nr_php_observer_fcall_begin_instrumented;
}
}
return begin;
}

static zend_observer_fcall_end_handler nr_php_observer_determine_end_handler(nruserfn_t* wraprec) {
zend_observer_fcall_end_handler end = NULL;

if (NULL == wraprec) {
if (NRINI(tt_detail)) {
end = nr_php_observer_fcall_end;
} else {
end = nr_php_observer_empty_fcall_end;
}
} else {
if (wraprec->special_instrumentation) {
end = (zend_observer_fcall_end_handler)wraprec->special_instrumentation;
} else if (wraprec->is_exception_handler) {
end = nr_php_observer_fcall_end_exception_handler;
} else if (wraprec->create_metric) {
end = nr_php_observer_fcall_end_create_metric;
} else {
end = nr_php_observer_fcall_end;
}
}
return end;
}

static zend_observer_fcall_handlers nr_php_fcall_register_handlers(
zend_execute_data* execute_data) {
zend_observer_fcall_handlers handlers = {NULL, NULL};
Expand All @@ -103,32 +151,11 @@ static zend_observer_fcall_handlers nr_php_fcall_register_handlers(
// printf("REGISTER %s\n", ZSTR_VAL(execute_data->func->common.function_name));
//}
wraprec = nr_php_get_wraprec(execute_data->func);
if (wraprec == NULL) {
if (0 == NRINI(tt_detail)) {
handlers.begin = nr_php_observer_empty_fcall_begin;
handlers.end = nr_php_observer_empty_fcall_end;
return handlers;
} else {
handlers.begin = nr_php_observer_fcall_begin;
handlers.end = nr_php_observer_fcall_end;
return handlers;
}
handlers.begin = nr_php_observer_determine_begin_handler(wraprec);
handlers.end = nr_php_observer_determine_end_handler(wraprec);
if (wraprec) {
nr_txn_force_single_count(NRPRG(txn), wraprec->supportability_metric);
}
handlers.begin = wraprec->special_instrumentation_before ?
(zend_observer_fcall_begin_handler) wraprec->special_instrumentation_before :
wraprec->is_transient ?
nr_php_observer_fcall_begin :
wraprec->is_names_wt_simple ?
nr_php_observer_fcall_begin_name_transaction :
nr_php_observer_fcall_begin_instrumented;
handlers.end = wraprec->special_instrumentation ?
(zend_observer_fcall_end_handler) wraprec->special_instrumentation :
wraprec->is_exception_handler ?
nr_php_observer_fcall_end_exception_handler :
wraprec->create_metric ?
nr_php_observer_fcall_end_create_metric :
nr_php_observer_fcall_end;
nr_txn_force_single_count(NRPRG(txn), wraprec->supportability_metric);
return handlers;
}

Expand All @@ -143,25 +170,36 @@ bool nr_php_observer_is_registered(zend_function* func) {
return (begin_handler && *begin_handler);
}

void nr_php_observer_overwrite_handlers(zend_function* func, nruserfn_t* wraprec) {
if (nr_php_observer_is_registered(func)) {
if (zend_observer_remove_begin_handler(func, NRINI(tt_detail) ?
nr_php_observer_fcall_begin :
nr_php_observer_empty_fcall_begin)) {
zend_observer_add_begin_handler(func, wraprec->special_instrumentation_before ?
(zend_observer_fcall_begin_handler)wraprec->special_instrumentation_before :
nr_php_observer_fcall_begin);
}
if (zend_observer_remove_end_handler(func, NRINI(tt_detail) ?
nr_php_observer_fcall_end :
nr_php_observer_empty_fcall_end)) {
zend_observer_add_end_handler(func, wraprec->special_instrumentation ?
(zend_observer_fcall_end_handler)wraprec->special_instrumentation :
wraprec->is_exception_handler ?
nr_php_observer_fcall_end_exception_handler :
nr_php_observer_fcall_end);
}
bool nr_php_observer_remove_begin_handler(zend_function* func, nruserfn_t* wraprec) {
if (!nr_php_observer_is_registered(func)) {
return false;
}
zend_observer_fcall_begin_handler begin = nr_php_observer_determine_begin_handler(wraprec);;
return zend_observer_remove_begin_handler(func, begin);
}

bool nr_php_observer_remove_end_handler(zend_function* func, nruserfn_t* wraprec) {
if (!nr_php_observer_is_registered(func)) {
return false;
}
zend_observer_fcall_end_handler end = nr_php_observer_determine_end_handler(wraprec);
return zend_observer_remove_end_handler(func, end);
}

void nr_php_observer_add_begin_handler(zend_function* func, nruserfn_t* wraprec) {
if (!nr_php_observer_is_registered(func)) {
return;
}
zend_observer_fcall_begin_handler begin = nr_php_observer_determine_begin_handler(wraprec);;
zend_observer_add_begin_handler(func, begin);
}

void nr_php_observer_add_end_handler(zend_function* func, nruserfn_t* wraprec) {
if (!nr_php_observer_is_registered(func)) {
return;
}
zend_observer_fcall_end_handler end = nr_php_observer_determine_end_handler(wraprec);
zend_observer_add_end_handler(func, end);
}
#endif

Expand Down
9 changes: 8 additions & 1 deletion agent/php_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,15 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,

#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
bool nr_php_observer_is_registered(zend_function* func);
void nr_php_observer_overwrite_handlers(zend_function* func, nruserfn_t* wraprec);
bool nr_php_observer_remove_begin_handler(zend_function* func, nruserfn_t* wraprec);
bool nr_php_observer_remove_end_handler(zend_function* func, nruserfn_t* wraprec);
void nr_php_observer_add_begin_handler(zend_function* func, nruserfn_t* wraprec);
void nr_php_observer_add_end_handler(zend_function* func, nruserfn_t* wraprec);

/*
* These different forms of fcall_begin and fcall_end are needed to properly utilize
* the fields in a wraprec without looking it up every call.
*/
void nr_php_observer_empty_fcall_begin(zend_execute_data* execute_data);
void nr_php_observer_fcall_begin_instrumented(zend_execute_data* execute_data);
void nr_php_observer_fcall_begin_name_transaction(zend_execute_data* execute_data);
Expand Down
52 changes: 37 additions & 15 deletions agent/php_user_instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,21 +254,21 @@ static void nr_php_wrap_zend_function(zend_function* func,
}
}

static zend_function* nr_php_wrap_user_function_internal(nruserfn_t* wraprec TSRMLS_DC) {
static void nr_php_wrap_user_function_internal(nruserfn_t* wraprec TSRMLS_DC) {
zend_function* orig_func = 0;

if (0 == NR_PHP_PROCESS_GLOBALS(done_instrumentation)) {
return NULL;
return;
}

if (wraprec->is_wrapped) {
return NULL;
return;
}

#if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO \
&& defined OVERWRITE_ZEND_EXECUTE_DATA /* PHP8+ */
if (nrunlikely(-1 == NR_PHP_PROCESS_GLOBALS(zend_offset))) {
return NULL;
return;
}
#endif
if (0 == wraprec->classname) {
Expand All @@ -282,8 +282,9 @@ static zend_function* nr_php_wrap_user_function_internal(nruserfn_t* wraprec TSR

if (NULL == orig_func) {
/* It could be in a file not yet loaded, no reason to log anything. */
return NULL;
return;
}
wraprec->func = orig_func;

if (ZEND_USER_FUNCTION != orig_func->type) {
nrl_verbosedebug(NRL_INSTRUMENT, "%s%s%s is not a user function",
Expand All @@ -295,10 +296,9 @@ static zend_function* nr_php_wrap_user_function_internal(nruserfn_t* wraprec TSR
* logs with this message.
*/
wraprec->is_disabled = 1;
return NULL;
return;
}
nr_php_wrap_zend_function(orig_func, wraprec TSRMLS_CC);
return orig_func;
}

static nruserfn_t* nr_php_user_wraprec_create(void) {
Expand Down Expand Up @@ -429,6 +429,10 @@ nruserfn_t* nr_php_add_custom_tracer_callable(zend_function* func TSRMLS_DC) {
nrl_verbosedebug(NRL_INSTRUMENT, "reusing custom wrapper for callable '%s'",
name);
nr_free(name);
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_remove_begin_handler(func, wraprec);
nr_php_observer_remove_end_handler(func, wraprec);
#endif
return wraprec;
}

Expand All @@ -442,6 +446,10 @@ nruserfn_t* nr_php_add_custom_tracer_callable(zend_function* func TSRMLS_DC) {
#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO
nr_php_add_custom_tracer_common(wraprec);
#endif
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_remove_begin_handler(func, NULL);
nr_php_observer_remove_end_handler(func, NULL);
#endif

return wraprec;
}
Expand All @@ -450,9 +458,6 @@ nruserfn_t* nr_php_add_custom_tracer_named(const char* namestr,
size_t namestrlen) {
nruserfn_t* wraprec;
nruserfn_t* p;
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
zend_function* orig_func;
#endif

wraprec = nr_php_user_wraprec_create_named(namestr, namestrlen);
if (0 == wraprec) {
Expand All @@ -472,6 +477,10 @@ nruserfn_t* nr_php_add_custom_tracer_named(const char* namestr,

nr_php_user_wraprec_destroy(&wraprec);
nr_php_wrap_user_function_internal(p TSRMLS_CC);
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_remove_begin_handler(p->func, wraprec);
nr_php_observer_remove_end_handler(p->func, wraprec);
#endif
return p; /* return the wraprec we are duplicating */
}
p = p->next;
Expand All @@ -482,18 +491,15 @@ nruserfn_t* nr_php_add_custom_tracer_named(const char* namestr,
NRP_PHP(wraprec->classname),
(0 == wraprec->classname) ? "" : "::", NRP_PHP(wraprec->funcname));

#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
orig_func = nr_php_wrap_user_function_internal(wraprec TSRMLS_CC);
#else
nr_php_wrap_user_function_internal(wraprec TSRMLS_CC);
#endif
/* non-transient wraprecs are added to both the hashmap and linked list.
* At request shutdown, the hashmap will free transients, but leave
* non-transients to be freed when the linked list is disposed of which is at
* module shutdown */
nr_php_add_custom_tracer_common(wraprec);
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_overwrite_handlers(orig_func, wraprec);
nr_php_observer_remove_begin_handler(wraprec->func, NULL);
nr_php_observer_remove_end_handler(wraprec->func, NULL);
#endif

return wraprec; /* return the new wraprec */
Expand Down Expand Up @@ -579,6 +585,10 @@ void nr_php_add_transaction_naming_function(const char* namestr,

if (NULL != wraprec) {
wraprec->is_names_wt_simple = 1;
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_add_begin_handler(wraprec->func, wraprec);
nr_php_observer_add_end_handler(wraprec->func, wraprec);
#endif
}
}

Expand All @@ -588,6 +598,10 @@ void nr_php_add_custom_tracer(const char* namestr, int namestrlen TSRMLS_DC) {
if (NULL != wraprec) {
wraprec->create_metric = 1;
wraprec->is_user_added = 1;
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_add_begin_handler(wraprec->func, wraprec);
nr_php_observer_add_end_handler(wraprec->func, wraprec);
#endif
}
}

Expand All @@ -596,6 +610,10 @@ void nr_php_add_exception_function(zend_function* func TSRMLS_DC) {

if (wraprec) {
wraprec->is_exception_handler = 1;
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_add_begin_handler(func, wraprec);
nr_php_observer_add_end_handler(func, wraprec);
#endif
}
}

Expand Down Expand Up @@ -651,6 +669,10 @@ void nr_php_user_function_add_declared_callback(const char* namestr,
if (wraprec->is_wrapped && callback) {
(callback)(TSRMLS_C);
}
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
nr_php_observer_add_begin_handler(wraprec->func, wraprec);
nr_php_observer_add_end_handler(wraprec->func, wraprec);
#endif
}
}

Expand Down
3 changes: 3 additions & 0 deletions agent/php_user_instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ typedef struct _nruserfn_t {
#if ZEND_MODULE_API_NO >= ZEND_7_4_X_API_NO
char* wordpress_plugin_theme;
#endif
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
zend_function* func; /* the underlying function that this wraprec wraps */
#endif
} nruserfn_t;

extern nruserfn_t* nr_wrapped_user_functions; /* a singly linked list */
Expand Down
Loading

0 comments on commit 6a46a5d

Please sign in to comment.