mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
[Observer] Save opline before calling begin/end handlers
This commit is contained in:
parent
1aff51d421
commit
855d8fa68f
@ -3956,8 +3956,9 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
LOAD_OPLINE_EX();
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
}
|
||||
@ -3981,8 +3982,9 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
LOAD_OPLINE_EX();
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
@ -4075,13 +4077,15 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -4299,6 +4303,7 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
|
||||
}
|
||||
}
|
||||
}
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_END(execute_data, return_value);
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
@ -8511,12 +8516,14 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
|
||||
}
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
|
@ -1350,9 +1350,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
}
|
||||
|
||||
@ -1374,9 +1374,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
}
|
||||
|
||||
@ -1398,8 +1398,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_OBS
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
LOAD_OPLINE_EX();
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
}
|
||||
@ -1423,9 +1424,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
@ -1517,9 +1518,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
@ -1611,8 +1612,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
LOAD_OPLINE_EX();
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
@ -1708,9 +1710,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -1813,9 +1818,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -1915,13 +1923,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
||||
call->prev_execute_data = execute_data;
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC);
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -3136,12 +3146,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
}
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -3270,12 +3282,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
|
||||
}
|
||||
execute_data = call;
|
||||
i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC);
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
if (EXPECTED(zend_execute_ex == execute_ex)) {
|
||||
LOAD_OPLINE_EX();
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
SAVE_OPLINE_EX();
|
||||
zend_observer_fcall_begin(execute_data);
|
||||
execute_data = EX(prev_execute_data);
|
||||
LOAD_OPLINE();
|
||||
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
|
||||
@ -4069,6 +4083,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@ -4141,6 +4156,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSER
|
||||
}
|
||||
}
|
||||
}
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_end(execute_data, return_value);
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
@ -18574,6 +18590,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@ -21139,6 +21156,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@ -37670,6 +37688,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@ -54736,6 +54755,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@ -54809,6 +54829,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
}
|
||||
}
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_end(execute_data, return_value);
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
@ -56344,6 +56365,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@ -56642,6 +56664,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@ -57756,6 +57779,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
|
@ -794,6 +794,7 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec=null)
|
||||
($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
|
||||
: "\\0",
|
||||
"/ZEND_OBSERVER_ENABLED/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "1" : "0",
|
||||
"/ZEND_OBSERVER_SAVE_OPLINE\(\)/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "SAVE_OPLINE()" : "",
|
||||
"/ZEND_OBSERVER_FCALL_BEGIN\(\s*(.*)\s*\)/" => isset($extra_spec['OBSERVER']) ?
|
||||
($extra_spec['OBSERVER'] == 0 ? "" : "zend_observer_fcall_begin(\\1)")
|
||||
: "",
|
||||
|
@ -37,6 +37,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
|
||||
int observer_show_return_type;
|
||||
int observer_show_return_value;
|
||||
int observer_show_init_backtrace;
|
||||
int observer_show_opcode;
|
||||
int observer_nesting_depth;
|
||||
ZEND_END_MODULE_GLOBALS(zend_test)
|
||||
|
||||
@ -330,6 +331,7 @@ PHP_INI_BEGIN()
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_type", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_type, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observer.show_return_value", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_return_value, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observer.show_init_backtrace", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_init_backtrace, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observer.show_opcode", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_show_opcode, zend_zend_test_globals, zend_test_globals)
|
||||
PHP_INI_END()
|
||||
|
||||
static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execute_data);
|
||||
@ -441,6 +443,14 @@ PHP_MSHUTDOWN_FUNCTION(zend_test)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static void observer_show_opcode(zend_execute_data *execute_data)
|
||||
{
|
||||
if (!ZT_G(observer_show_opcode)) {
|
||||
return;
|
||||
}
|
||||
php_printf("%*s<!-- opcode: '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", zend_get_opcode_name(EX(opline)->opcode));
|
||||
}
|
||||
|
||||
static void observer_begin(zend_execute_data *execute_data)
|
||||
{
|
||||
if (!ZT_G(observer_show_output)) {
|
||||
@ -457,6 +467,7 @@ static void observer_begin(zend_execute_data *execute_data)
|
||||
php_printf("%*s<file '%s'>\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(execute_data->func->op_array.filename));
|
||||
}
|
||||
ZT_G(observer_nesting_depth)++;
|
||||
observer_show_opcode(execute_data);
|
||||
}
|
||||
|
||||
static void get_retval_info(zval *retval, smart_str *buf)
|
||||
@ -485,6 +496,7 @@ static void observer_end(zend_execute_data *execute_data, zval *retval)
|
||||
if (EG(exception)) {
|
||||
php_printf("%*s<!-- Exception: %s -->\n", 2 * ZT_G(observer_nesting_depth), "", ZSTR_VAL(EG(exception)->ce->name));
|
||||
}
|
||||
observer_show_opcode(execute_data);
|
||||
ZT_G(observer_nesting_depth)--;
|
||||
if (execute_data->func && execute_data->func->common.function_name) {
|
||||
smart_str retval_info = {0};
|
||||
@ -541,6 +553,7 @@ static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execu
|
||||
if (ZT_G(observer_show_init_backtrace)) {
|
||||
observer_show_init_backtrace(execute_data);
|
||||
}
|
||||
observer_show_opcode(execute_data);
|
||||
}
|
||||
|
||||
if (ZT_G(observer_observe_all)) {
|
||||
|
53
ext/zend_test/tests/observer_opline_01.phpt
Normal file
53
ext/zend_test/tests/observer_opline_01.phpt
Normal file
@ -0,0 +1,53 @@
|
||||
--TEST--
|
||||
Observer: Ensure opline exists on the execute_data
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_opcode=1
|
||||
--FILE--
|
||||
<?php
|
||||
function foo()
|
||||
{
|
||||
echo 'Foo' . PHP_EOL;
|
||||
}
|
||||
|
||||
foo();
|
||||
include __DIR__ . '/observer.inc';
|
||||
echo array_sum([1,2,3]) . PHP_EOL;
|
||||
foo();
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_opline_%d.php' -->
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<file '%s/observer_opline_%d.php'>
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<!-- init foo() -->
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
<foo>
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
Foo
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo>
|
||||
<!-- init '%s/observer.inc' -->
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<file '%s/observer.inc'>
|
||||
<!-- opcode: 'ZEND_INIT_FCALL' -->
|
||||
<!-- init foo_observer_test() -->
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
<foo_observer_test>
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
foo_observer_test
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo_observer_test>
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</file '%s/observer.inc'>
|
||||
6
|
||||
<foo>
|
||||
<!-- opcode: 'ZEND_ECHO' -->
|
||||
Foo
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</foo>
|
||||
<!-- opcode: 'ZEND_RETURN' -->
|
||||
</file '%s/observer_opline_%d.php'>
|
Loading…
Reference in New Issue
Block a user