Skip to content

Commit ee9e135

Browse files
committed
Cache scope for end hook as it may be invalidated before
Signed-off-by: Bob Weinand <[email protected]>
1 parent 7c51afb commit ee9e135

3 files changed

Lines changed: 13 additions & 12 deletions

File tree

ext/hook/uhook.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ typedef struct {
7474

7575
typedef struct {
7676
dd_hook_data *hook_data;
77+
zend_class_entry *called_scope;
7778
} dd_uhook_dynamic;
7879

7980
#if PHP_VERSION_ID < 70400
@@ -234,14 +235,14 @@ void dd_uhook_report_sandbox_error(zend_execute_data *execute_data, zend_object
234235
})
235236
}
236237

237-
static bool dd_uhook_call_hook(zend_execute_data *execute_data, dd_uhook_callback *callback, dd_hook_data *hook_data) {
238+
static bool dd_uhook_call_hook(zend_execute_data *execute_data, dd_uhook_callback *callback, dd_hook_data *hook_data, zend_class_entry *scope) {
238239
zval hook_data_zv;
239240
ZVAL_OBJ(&hook_data_zv, &hook_data->std);
240241

241242
zval rv;
242243
zai_sandbox sandbox;
243244
zai_sandbox_open(&sandbox);
244-
dd_uhook_callback_ensure_scope(callback, execute_data);
245+
dd_uhook_callback_ensure_scope(callback, execute_data, scope);
245246
zend_fcall_info fci = dd_fcall_info(1, &hook_data_zv, &rv);
246247
bool success = zai_sandbox_call(&sandbox, &fci, &callback->fcc);
247248
if (!success || PG(last_error_message)) {
@@ -321,6 +322,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat
321322
return true;
322323
}
323324

325+
dyn->called_scope = zend_get_called_scope(execute_data);
324326
dyn->hook_data = (dd_hook_data *)dd_hook_data_create(ddtrace_hook_data_ce);
325327
dyn->hook_data->returns_reference = execute_data->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE;
326328
dyn->hook_data->vm_stack_top = EG(vm_stack_top);
@@ -356,7 +358,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat
356358
LOGEV(HOOK_TRACE, dd_uhook_log_invocation(log, execute_data, "begin", def->begin.closure););
357359

358360
def->running = true;
359-
dd_uhook_call_hook(execute_data, &def->begin, dyn->hook_data);
361+
dd_uhook_call_hook(execute_data, &def->begin, dyn->hook_data, dyn->called_scope);
360362
def->running = false;
361363
dyn->hook_data->retval_ptr = NULL;
362364
}
@@ -480,7 +482,7 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data,
480482
def->running = true;
481483
dyn->hook_data->retval_ptr = retval;
482484
dyn->hook_data->execute_data = execute_data;
483-
keep_span = dd_uhook_call_hook(execute_data, &def->end, dyn->hook_data);
485+
keep_span = dd_uhook_call_hook(execute_data, &def->end, dyn->hook_data, dyn->called_scope);
484486
dyn->hook_data->execute_data = NULL;
485487
dyn->hook_data->retval_ptr = NULL;
486488
def->running = false;

ext/hook/uhook.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ void zai_uhook_minit(int module_number);
2222
void zai_uhook_mshutdown();
2323

2424
void dd_uhook_callback_apply_scope(dd_uhook_callback *cb, zend_class_entry *scope);
25-
static inline void dd_uhook_callback_ensure_scope(dd_uhook_callback *cb, zend_execute_data *execute_data) {
26-
zend_class_entry *scope;
25+
// Note that we cannot access zend_get_called_scope(execute_data) here - we need to have it provided from earlier, it might have been invalidated by now, e.g. in ZEND_NAMED_FUNCTION(zend_closure_internal_handler).
26+
static inline void dd_uhook_callback_ensure_scope(dd_uhook_callback *cb, zend_execute_data *execute_data, zend_class_entry *scope) {
2727
if (!cb->fcc.function_handler) {
28-
scope = zend_get_called_scope(execute_data);
2928
goto apply_scope;
3029
} else if (!cb->is_static) {
3130
bool has_this;
32-
scope = zend_get_called_scope(execute_data);
3331
if (scope != cb->fcc.called_scope) {
3432
apply_scope:
3533
dd_uhook_callback_apply_scope(cb, scope);

ext/hook/uhook_legacy.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ typedef struct {
2424
typedef struct {
2525
zend_array *args;
2626
ddtrace_span_data *span;
27+
zend_class_entry *called_scope;
2728
bool skipped;
2829
bool dropped_span;
2930
bool was_primed;
@@ -35,7 +36,7 @@ static bool dd_uhook_call(dd_uhook_callback *callback, bool tracing, dd_uhook_dy
3536

3637
#define ZVAL_EXCEPTION(zv) do { if (EG(exception)) ZVAL_OBJ(zv, EG(exception)); else ZVAL_NULL(zv); } while (0)
3738
if (tracing) {
38-
dd_uhook_callback_ensure_scope(callback, execute_data);
39+
dd_uhook_callback_ensure_scope(callback, execute_data, dyn->called_scope);
3940

4041
ZVAL_OBJ(&params[0], &dyn->span->std);
4142
ZVAL_ARR(&params[1], dyn->args);
@@ -62,9 +63,8 @@ static bool dd_uhook_call(dd_uhook_callback *callback, bool tracing, dd_uhook_dy
6263
ZVAL_COPY_VALUE(&params[0], This);
6364
callback->fcc.object = Z_OBJ_P(This);
6465
}
65-
zend_class_entry *scope_ce = zend_get_called_scope(execute_data);
66-
if (scope_ce) {
67-
ZVAL_STR(&params[1], scope_ce->name);
66+
if (dyn->called_scope) {
67+
ZVAL_STR(&params[1], dyn->called_scope->name);
6868
} else {
6969
ZVAL_NULL(&params[1]);
7070
}
@@ -108,6 +108,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat
108108
dyn->skipped = false;
109109
dyn->was_primed = false;
110110
dyn->dropped_span = false;
111+
dyn->called_scope = zend_get_called_scope(execute_data);
111112
dyn->args = dd_uhook_collect_args(execute_data);
112113

113114
if (def->tracing) {

0 commit comments

Comments
 (0)