Skip to content

Commit 41d4fc2

Browse files
committed
fix double segments
1 parent c99b864 commit 41d4fc2

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

@@ -2307,7 +2335,7 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
23072335
}
23082336

23092337
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
2310-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false);
2338+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, true);
23112339
#else
23122340
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS);
23132341
#endif
@@ -2323,6 +2351,41 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
23232351
// has been added This is needed because the process for adding instrumentation
23242352
// with a transient wrapper differs depending on if the function has been
23252353
// previously called. These will only be used when tt_detail is 0.
2354+
void nr_php_observer_fcall_end_keep_segment(zend_execute_data* execute_data,
2355+
zval* func_return_value) {
2356+
/*
2357+
* Instrument the function.
2358+
* This and any other needed helper functions will replace:
2359+
* nr_php_execute_enabled
2360+
* nr_php_execute
2361+
* nr_php_execute_show
2362+
*/
2363+
if (nrunlikely(NULL == execute_data)) {
2364+
return;
2365+
}
2366+
//if (execute_data->func && execute_data->func->common.function_name) {
2367+
// printf("END %s\n", ZSTR_VAL(execute_data->func->common.function_name));
2368+
//}
2369+
2370+
if (nrlikely(1 == nr_php_recording())) {
2371+
int show_executes_return
2372+
= NR_PHP_PROCESS_GLOBALS(special_flags).show_execute_returns;
2373+
2374+
if (nrunlikely(show_executes_return)) {
2375+
nrl_verbosedebug(NRL_AGENT,
2376+
"Stack depth: %d before OAPI function exiting via %s",
2377+
NRPRG(php_cur_stack_depth), __func__);
2378+
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
2379+
}
2380+
2381+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, false);
2382+
}
2383+
2384+
NRPRG(php_cur_stack_depth) -= 1;
2385+
2386+
return;
2387+
}
2388+
23262389
void nr_php_observer_empty_fcall_begin(zend_execute_data* execute_data) {
23272390
(void)execute_data;
23282391
}
@@ -2360,7 +2423,7 @@ void nr_php_observer_fcall_end_create_metric(zend_execute_data* execute_data,
23602423
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
23612424
}
23622425

2363-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true);
2426+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true, true);
23642427
}
23652428

23662429
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)