Skip to content

Commit 26f71a6

Browse files
committed
fix double segments
1 parent 0b7b853 commit 26f71a6

File tree

6 files changed

+94
-13
lines changed

6 files changed

+94
-13
lines changed

agent/fw_wordpress.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,11 +749,9 @@ NR_PHP_WRAPPER(nr_wordpress_apply_filters_after) {
749749
nr_wordpress_name_the_wt(tag, retval_ptr TSRMLS_CC);
750750
}
751751

752-
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
753-
nr_wordpress_handle_tag_stack_after(execute_data);
754-
#else
755-
nr_wordpress_handle_tag_stack_after(NR_SPECIALFNPTR_ORIG_ARGS);
756-
#endif
752+
if (0 != NRINI(wordpress_hooks)) {
753+
clean_wordpress_tag_stack(auto_segment);
754+
}
757755
}
758756
NR_PHP_WRAPPER_END
759757
#endif /* OAPI */

agent/php_execute.c

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,16 +2047,40 @@ void nr_php_observer_fcall_begin_late(zend_execute_data* execute_data, nrtime_t
20472047
}
20482048
#endif
20492049

2050+
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
2051+
void nr_php_observer_fcall_end_late(zend_execute_data* execute_data, bool create_metric, nrtime_t txn_start_time) {
2052+
nr_segment_t* segment;
2053+
nr_php_execute_metadata_t metadata = {0};
2054+
if (nrunlikely(nr_txn_start_time(NRPRG(txn)) != txn_start_time)) {
2055+
nrl_verbosedebug(NRL_AGENT,
2056+
"%s txn ended and/or started while in a wrapped function",
2057+
__func__);
2058+
2059+
return;
2060+
}
2061+
2062+
/*
2063+
* Reassign segment to the current segment, as some before/after wraprecs
2064+
* start and then stop a segment. If that happened, we want to ensure we
2065+
* get the now-current segment
2066+
*/
2067+
segment = nr_txn_get_current_segment(NRPRG(txn), NULL);
2068+
nr_php_execute_metadata_init(&metadata, NR_OP_ARRAY);
2069+
nr_php_execute_segment_end(segment, &metadata, create_metric);
2070+
nr_php_execute_metadata_release(&metadata);
2071+
}
2072+
#endif
2073+
20502074
#if ZEND_MODULE_API_NO < ZEND_8_2_X_API_NO
20512075
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO) {
20522076
int zcaught = 0;
20532077
nruserfn_t* wraprec = NULL;
20542078
bool create_metric = false;
2079+
nr_php_execute_metadata_t metadata = {0};
20552080
#else
2056-
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
2081+
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric, bool end_segment) {
20572082
#endif
20582083
nr_segment_t* segment = NULL;
2059-
nr_php_execute_metadata_t metadata = {0};
20602084
nrtime_t txn_start_time = 0;
20612085

20622086
if (NULL == NRPRG(txn)) {
@@ -2159,7 +2183,6 @@ static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
21592183
nr_segment_discard(&segment);
21602184
return;
21612185
}
2162-
#endif
21632186
/*
21642187
* During nr_zend_call_orig_execute_special, the transaction may have been
21652188
* ended and/or a new transaction may have started. To detect this, we
@@ -2187,6 +2210,11 @@ static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
21872210
nr_php_execute_metadata_init(&metadata, NR_OP_ARRAY);
21882211
nr_php_execute_segment_end(segment, &metadata, create_metric);
21892212
nr_php_execute_metadata_release(&metadata);
2213+
#else
2214+
if (end_segment) {
2215+
nr_php_observer_fcall_end_late(execute_data, create_metric, txn_start_time);
2216+
}
2217+
#endif
21902218
return;
21912219
}
21922220

@@ -2304,7 +2332,7 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
23042332
}
23052333

23062334
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
2307-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false);
2335+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, true);
23082336
#else
23092337
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS);
23102338
#endif
@@ -2320,6 +2348,41 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
23202348
// has been added This is needed because the process for adding instrumentation
23212349
// with a transient wrapper differs depending on if the function has been
23222350
// previously called. These will only be used when tt_detail is 0.
2351+
void nr_php_observer_fcall_end_keep_segment(zend_execute_data* execute_data,
2352+
zval* func_return_value) {
2353+
/*
2354+
* Instrument the function.
2355+
* This and any other needed helper functions will replace:
2356+
* nr_php_execute_enabled
2357+
* nr_php_execute
2358+
* nr_php_execute_show
2359+
*/
2360+
if (nrunlikely(NULL == execute_data)) {
2361+
return;
2362+
}
2363+
//if (execute_data->func && execute_data->func->common.function_name) {
2364+
// printf("END %s\n", ZSTR_VAL(execute_data->func->common.function_name));
2365+
//}
2366+
2367+
if (nrlikely(1 == nr_php_recording())) {
2368+
int show_executes_return
2369+
= NR_PHP_PROCESS_GLOBALS(special_flags).show_execute_returns;
2370+
2371+
if (nrunlikely(show_executes_return)) {
2372+
nrl_verbosedebug(NRL_AGENT,
2373+
"Stack depth: %d before OAPI function exiting via %s",
2374+
NRPRG(php_cur_stack_depth), __func__);
2375+
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
2376+
}
2377+
2378+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, false);
2379+
}
2380+
2381+
NRPRG(php_cur_stack_depth) -= 1;
2382+
2383+
return;
2384+
}
2385+
23232386
void nr_php_observer_empty_fcall_begin(zend_execute_data* execute_data) {
23242387
(void)execute_data;
23252388
}
@@ -2354,7 +2417,7 @@ void nr_php_observer_fcall_end_create_metric(zend_execute_data* execute_data,
23542417
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
23552418
}
23562419

2357-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true);
2420+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true, true);
23582421
}
23592422

23602423
NRPRG(php_cur_stack_depth) -= 1;

agent/php_newrelic.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,11 @@ int symfony1_in_dispatch; /* Whether we are currently within a
450450
int symfony1_in_error404; /* Whether we are currently within a
451451
sfError404Exception::printStackTrace() frame */
452452

453+
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO \
454+
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
455+
bool in_wrapper;
456+
#endif
457+
453458
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
454459
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
455460
bool check_cufa;

agent/php_observer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ void nr_php_observer_fcall_begin_instrumented(zend_execute_data* execute_data);
8787
void nr_php_observer_empty_fcall_end(zend_execute_data* execute_data,
8888
zval* func_return_value);
8989
void nr_php_observer_fcall_begin_late(zend_execute_data* execute_data, nrtime_t txn_start_time);
90+
void nr_php_observer_fcall_end_keep_segment(zend_execute_data* execute_data,
91+
zval* func_return_value);
92+
void nr_php_observer_fcall_end_late(zend_execute_data* execute_data, bool create_metric, nrtime_t txn_start_time);
9093
void nr_php_observer_fcall_end_create_metric(zend_execute_data* execute_data,
9194
zval* func_return_value);
9295
#endif /* PHP 8.2+ */

agent/php_rinit.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ PHP_RINIT_FUNCTION(newrelic) {
126126
NRPRG(predis_ctxs).dtor = str_stack_dtor;
127127
NRPRG(drupal_invoke_all_hooks).dtor = zval_stack_dtor;
128128
#endif
129+
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO \
130+
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
131+
NRPRG(in_wrapper) = false;
132+
#endif
129133

130134
NRPRG(mysql_last_conn) = NULL;
131135
NRPRG(pgsql_last_conn) = NULL;

agent/php_wrapper.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,21 @@ extern zval** nr_php_get_return_value_ptr(TSRMLS_D);
276276
zval** func_return_value_ptr = NULL; \
277277
const nrtxn_t* txn = NRPRG(txn); \
278278
const nrtime_t txn_start_time = nr_txn_start_time(txn); \
279+
if (NRPRG(in_wrapper)) { \
280+
printf("AAHHHHHHHHHHH\n"); \
281+
} \
282+
NRPRG(in_wrapper) = true; \
279283
\
280284
nr_segment_t* auto_segment = nr_txn_get_current_segment(NRPRG(txn), NULL); \
281-
if (!auto_segment || auto_segment->execute_data != execute_data) { \
285+
if (!auto_segment || auto_segment->execute_data != execute_data || \
286+
auto_segment == NRPRG(txn)->segment_root) { \
282287
nr_php_observer_fcall_begin(execute_data); \
283288
auto_segment = nr_txn_get_current_segment(NRPRG(txn), NULL); \
284289
is_begin = true; \
285290
} else { \
286291
func_return_value_ptr = nr_php_get_return_value_ptr(); \
287292
func_return_value = func_return_value_ptr ? *func_return_value_ptr : NULL;\
288-
nr_php_observer_fcall_end(execute_data, \
293+
nr_php_observer_fcall_end_keep_segment(execute_data, \
289294
func_return_value_ptr ? *func_return_value_ptr : NULL); \
290295
}
291296
#endif
@@ -317,7 +322,10 @@ extern zval** nr_php_get_return_value_ptr(TSRMLS_D);
317322
} \
318323
if (is_begin) { \
319324
nr_php_observer_fcall_begin_late(execute_data, txn_start_time);\
320-
} \
325+
} else { \
326+
nr_php_observer_fcall_end_late(execute_data, false, txn_start_time); \
327+
} \
328+
NRPRG(in_wrapper) = false; \
321329
if (zcaught) { \
322330
zend_bailout(); \
323331
} \

0 commit comments

Comments
 (0)