Skip to content

Commit 6ed1863

Browse files
committed
use ZEND_OP_ARRAY_EXTENSION to store wraprec
1 parent 5c0086e commit 6ed1863

File tree

6 files changed

+38
-7
lines changed

6 files changed

+38
-7
lines changed

agent/php_execute.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@
9393
* conditions wherever possible.
9494
*/
9595

96+
static inline nruserfn_t* nr_php_get_wraprec_from_op_array_extension(const char* fn, zend_function* zf) {
97+
nruserfn_t* wraprec = (nruserfn_t*)ZEND_OP_ARRAY_EXTENSION(&zf->op_array, NR_PHP_PROCESS_GLOBALS(op_array_extension_handle));
98+
nrl_verbosedebug(NRL_AGENT, "%s from %s, op_array_extension=%p, wraprec=%p, wraprec->pid=%d", __func__, fn, ZEND_OP_ARRAY_EXTENSION(&zf->op_array, NR_PHP_PROCESS_GLOBALS(op_array_extension_handle)), wraprec, wraprec->pid);
99+
return wraprec;
100+
}
101+
96102
static void nr_php_show_exec_return(NR_EXECUTE_PROTO TSRMLS_DC);
97103
static int nr_php_show_exec_indentation(TSRMLS_D);
98104
static void nr_php_show_exec(NR_EXECUTE_PROTO TSRMLS_DC);
@@ -598,6 +604,7 @@ static void nr_php_show_exec(NR_EXECUTE_PROTO TSRMLS_DC) {
598604
char argstr[NR_EXECUTE_DEBUG_STRBUFSZ];
599605
const char* filename = nr_php_op_array_file_name(NR_OP_ARRAY);
600606
const char* function_name = nr_php_op_array_function_name(NR_OP_ARRAY);
607+
nruserfn_t* wr = nr_php_get_wraprec_from_op_array_extension(__func__, execute_data->func);
601608

602609
argstr[0] = '\0';
603610

@@ -621,7 +628,7 @@ static void nr_php_show_exec(NR_EXECUTE_PROTO TSRMLS_DC) {
621628
#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO
622629
nr_php_op_array_get_wraprec(NR_OP_ARRAY TSRMLS_CC) ? " *" : "",
623630
#else
624-
nr_php_get_wraprec(execute_data->func) ? " *" : "",
631+
wr ? " *" : "",
625632
#endif
626633
NRP_FILENAME(filename), NR_OP_ARRAY->line_start);
627634
} else if (NR_OP_ARRAY->function_name) {
@@ -642,7 +649,7 @@ static void nr_php_show_exec(NR_EXECUTE_PROTO TSRMLS_DC) {
642649
#if ZEND_MODULE_API_NO < ZEND_7_4_X_API_NO
643650
nr_php_op_array_get_wraprec(NR_OP_ARRAY TSRMLS_CC) ? " *" : "",
644651
#else
645-
nr_php_get_wraprec(execute_data->func) ? " *" : "",
652+
wr ? " *" : "",
646653
#endif
647654
NRP_FILENAME(filename), NR_OP_ARRAY->line_start);
648655
} else if (NR_OP_ARRAY->filename) {
@@ -1928,7 +1935,7 @@ static void nr_php_instrument_func_begin(NR_EXECUTE_PROTO) {
19281935
*/
19291936
nr_php_observer_attempt_call_cufa_handler(NR_EXECUTE_ORIG_ARGS);
19301937
}
1931-
wraprec = nr_php_get_wraprec(execute_data->func);
1938+
wraprec = nr_php_get_wraprec_from_op_array_extension(__func__, execute_data->func);
19321939

19331940
segment = nr_segment_start(NRPRG(txn), NULL, NULL);
19341941

agent/php_globals.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,10 @@ typedef struct _nrphpglobals_t {
4949
* variable with the key `NEW_RELIC_LABELS` */
5050
#if ZEND_MODULE_API_NO >= ZEND_8_1_X_API_NO /* PHP 8.1+ */
5151
zend_long zend_offset; /* Zend extension offset */
52-
zend_long
53-
zend_op_array_offset; /* Zend extension op_array to modify reserved */
5452
#else
5553
int zend_offset; /* Zend extension offset */
56-
int zend_op_array_offset; /* Zend extension op_array to modify reserved */
5754
#endif
55+
int op_array_extension_handle; /* Zend op_array extension handle to attach agent's data to function */
5856
int done_instrumentation; /* Set to true if we have installed instrumentation
5957
handlers */
6058
nrtime_t expensive_min; /* newrelic.special.expensive_node_min */

agent/php_minit.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,11 @@ PHP_MINIT_FUNCTION(newrelic) {
722722
nrl_debug(NRL_INIT, "MINIT processing done");
723723
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO /* PHP 7.4+ */
724724
NR_PHP_PROCESS_GLOBALS(zend_offset) = zend_get_resource_handle(dummy);
725+
#if ZEND_MODULE_API_NO >= ZEND_8_4_X_API_NO /* PHP 7.4+ */
726+
NR_PHP_PROCESS_GLOBALS(op_array_extension_handle) = zend_get_internal_function_extension_handle("newrelic");
727+
#else
728+
NR_PHP_PROCESS_GLOBALS(op_array_extension_handle) = zend_get_op_array_extension_handle("newrelic");
729+
#endif
725730
#else
726731
NR_PHP_PROCESS_GLOBALS(zend_offset) = zend_get_resource_handle(&dummy);
727732
#endif

agent/php_observer.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,27 @@
7575
static zend_observer_fcall_handlers nr_php_fcall_register_handlers(
7676
zend_execute_data* execute_data) {
7777
zend_observer_fcall_handlers handlers = {NULL, NULL};
78+
nruserfn_t* wr;
7879
if (NULL == execute_data) {
7980
return handlers;
8081
}
8182
if ((NULL == execute_data->func)
8283
|| (ZEND_INTERNAL_FUNCTION == execute_data->func->type)) {
8384
return handlers;
8485
}
86+
87+
if (!OP_ARRAY_IS_A_FILE(NR_OP_ARRAY)) {
88+
nrl_verbosedebug(NRL_AGENT, "Registering Observer API handlers for user function %s",
89+
NRSAFESTR(nr_php_op_array_function_name(NR_OP_ARRAY)));
90+
} else {
91+
nrl_verbosedebug(NRL_AGENT, "Registering Observer API handlers for file %s",
92+
NRSAFESTR(nr_php_op_array_file_name(NR_OP_ARRAY)));
93+
}
94+
95+
wr = nr_php_get_wraprec(execute_data->func);
96+
// store the wraprec in the op_array extension for the duration of the request for later lookup
97+
ZEND_OP_ARRAY_EXTENSION(&execute_data->func->op_array, NR_PHP_PROCESS_GLOBALS(op_array_extension_handle)) = wr;
98+
8599
handlers.begin = nr_php_observer_fcall_begin;
86100
handlers.end = nr_php_observer_fcall_end;
87101
return handlers;

agent/php_user_instrument.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ static nr_php_wraprec_hashmap_t* user_function_wrappers;
130130
static inline void nr_php_wraprec_lookup_set(nruserfn_t* wr,
131131
zend_function* zf) {
132132
nr_php_wraprec_hashmap_update(user_function_wrappers, zf, wr);
133+
// store the wraprec in the op_array extension for the duration of the request for later lookup
134+
// for situation when wraprec is added after first execution of the function
135+
ZEND_OP_ARRAY_EXTENSION(&zf->op_array, NR_PHP_PROCESS_GLOBALS(op_array_extension_handle)) = wr;
136+
133137
}
134138
static inline nruserfn_t* nr_php_wraprec_lookup_get(zend_function* zf) {
135139
nruserfn_t* wraprec = NULL;
@@ -291,7 +295,9 @@ static void nr_php_wrap_user_function_internal(nruserfn_t* wraprec TSRMLS_DC) {
291295
}
292296

293297
static nruserfn_t* nr_php_user_wraprec_create(void) {
294-
return (nruserfn_t*)nr_zalloc(sizeof(nruserfn_t));
298+
nruserfn_t* wr = (nruserfn_t*)nr_zalloc(sizeof(nruserfn_t));
299+
wr->pid = nr_getpid();
300+
return wr;
295301
}
296302

297303
static nruserfn_t* nr_php_user_wraprec_create_named(const char* full_name,

agent/php_user_instrument.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ typedef struct _nruserfn_t {
108108
#if ZEND_MODULE_API_NO >= ZEND_7_4_X_API_NO
109109
char* wordpress_plugin_theme;
110110
#endif
111+
int pid; /* pid of a process that created this wraprec */
111112
} nruserfn_t;
112113

113114
extern nruserfn_t* nr_wrapped_user_functions; /* a singly linked list */

0 commit comments

Comments
 (0)