Skip to content

Commit 0aa9c77

Browse files
committed
fix double segments
1 parent e3d2964 commit 0aa9c77

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
@@ -748,11 +748,9 @@ NR_PHP_WRAPPER(nr_wordpress_apply_filters_after) {
748748
nr_wordpress_name_the_wt(tag, retval_ptr TSRMLS_CC);
749749
}
750750

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

agent/php_execute.c

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,16 +2039,40 @@ void nr_php_observer_fcall_begin_late(zend_execute_data* execute_data, nrtime_t
20392039
}
20402040
#endif
20412041

2042+
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
2043+
void nr_php_observer_fcall_end_late(zend_execute_data* execute_data, bool create_metric, nrtime_t txn_start_time) {
2044+
nr_segment_t* segment;
2045+
nr_php_execute_metadata_t metadata = {0};
2046+
if (nrunlikely(nr_txn_start_time(NRPRG(txn)) != txn_start_time)) {
2047+
nrl_verbosedebug(NRL_AGENT,
2048+
"%s txn ended and/or started while in a wrapped function",
2049+
__func__);
2050+
2051+
return;
2052+
}
2053+
2054+
/*
2055+
* Reassign segment to the current segment, as some before/after wraprecs
2056+
* start and then stop a segment. If that happened, we want to ensure we
2057+
* get the now-current segment
2058+
*/
2059+
segment = nr_txn_get_current_segment(NRPRG(txn), NULL);
2060+
nr_php_execute_metadata_init(&metadata, NR_OP_ARRAY);
2061+
nr_php_execute_segment_end(segment, &metadata, create_metric);
2062+
nr_php_execute_metadata_release(&metadata);
2063+
}
2064+
#endif
2065+
20422066
#if ZEND_MODULE_API_NO < ZEND_8_2_X_API_NO
20432067
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO) {
20442068
int zcaught = 0;
20452069
nruserfn_t* wraprec = NULL;
20462070
bool create_metric = false;
2071+
nr_php_execute_metadata_t metadata = {0};
20472072
#else
2048-
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
2073+
static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric, bool end_segment) {
20492074
#endif
20502075
nr_segment_t* segment = NULL;
2051-
nr_php_execute_metadata_t metadata = {0};
20522076
nrtime_t txn_start_time = 0;
20532077

20542078
if (NULL == NRPRG(txn)) {
@@ -2151,7 +2175,6 @@ static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
21512175
nr_segment_discard(&segment);
21522176
return;
21532177
}
2154-
#endif
21552178
/*
21562179
* During nr_zend_call_orig_execute_special, the transaction may have been
21572180
* ended and/or a new transaction may have started. To detect this, we
@@ -2179,6 +2202,11 @@ static void nr_php_instrument_func_end(NR_EXECUTE_PROTO, bool create_metric) {
21792202
nr_php_execute_metadata_init(&metadata, NR_OP_ARRAY);
21802203
nr_php_execute_segment_end(segment, &metadata, create_metric);
21812204
nr_php_execute_metadata_release(&metadata);
2205+
#else
2206+
if (end_segment) {
2207+
nr_php_observer_fcall_end_late(execute_data, create_metric, txn_start_time);
2208+
}
2209+
#endif
21822210
return;
21832211
}
21842212

@@ -2299,7 +2327,7 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
22992327
}
23002328

23012329
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO
2302-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false);
2330+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, true);
23032331
#else
23042332
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS);
23052333
#endif
@@ -2315,6 +2343,41 @@ void nr_php_observer_fcall_end(zend_execute_data* execute_data,
23152343
// has been added This is needed because the process for adding instrumentation
23162344
// with a transient wrapper differs depending on if the function has been
23172345
// previously called. These will only be used when tt_detail is 0.
2346+
void nr_php_observer_fcall_end_keep_segment(zend_execute_data* execute_data,
2347+
zval* func_return_value) {
2348+
/*
2349+
* Instrument the function.
2350+
* This and any other needed helper functions will replace:
2351+
* nr_php_execute_enabled
2352+
* nr_php_execute
2353+
* nr_php_execute_show
2354+
*/
2355+
if (nrunlikely(NULL == execute_data)) {
2356+
return;
2357+
}
2358+
//if (execute_data->func && execute_data->func->common.function_name) {
2359+
// printf("END %s\n", ZSTR_VAL(execute_data->func->common.function_name));
2360+
//}
2361+
2362+
if (nrlikely(1 == nr_php_recording())) {
2363+
int show_executes_return
2364+
= NR_PHP_PROCESS_GLOBALS(special_flags).show_execute_returns;
2365+
2366+
if (nrunlikely(show_executes_return)) {
2367+
nrl_verbosedebug(NRL_AGENT,
2368+
"Stack depth: %d before OAPI function exiting via %s",
2369+
NRPRG(php_cur_stack_depth), __func__);
2370+
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
2371+
}
2372+
2373+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, false, false);
2374+
}
2375+
2376+
NRPRG(php_cur_stack_depth) -= 1;
2377+
2378+
return;
2379+
}
2380+
23182381
void nr_php_observer_empty_fcall_begin(zend_execute_data* execute_data) {
23192382
(void)execute_data;
23202383
}
@@ -2352,7 +2415,7 @@ void nr_php_observer_fcall_end_create_metric(zend_execute_data* execute_data,
23522415
nr_php_show_exec_return(NR_EXECUTE_ORIG_ARGS TSRMLS_CC);
23532416
}
23542417

2355-
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true);
2418+
nr_php_instrument_func_end(NR_EXECUTE_ORIG_ARGS, true, true);
23562419
}
23572420

23582421
NRPRG(php_cur_stack_depth) -= 1;

agent/php_newrelic.h

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

452+
#if ZEND_MODULE_API_NO >= ZEND_8_2_X_API_NO \
453+
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
454+
bool in_wrapper;
455+
#endif
456+
452457
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
453458
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
454459
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)