mirror of
https://github.com/python/cpython.git
synced 2026-06-05 01:10:53 +00:00
gh-98894: Restore function entry/exit DTrace probes (#142397)
The function__entry and function__return probes stopped working in Python 3.11 when the interpreter was restructured around the new bytecode system. This change restores these probes by adding DTRACE_FUNCTION_ENTRY() at the start_frame label in bytecodes.c and DTRACE_FUNCTION_RETURN() in the RETURN_VALUE and YIELD_VALUE instructions. The helper functions are defined in ceval.c and extract the filename, function name, and line number from the frame before firing the probe. This builds on the approach from https://github.com/python/cpython/pull/125019 but avoids modifying the JIT template since the JIT does not currently support DTrace. The macros are conditionally compiled with WITH_DTRACE and are no-ops otherwise. The tests have been updated to use modern opcode names (CALL, CALL_KW, CALL_FUNCTION_EX) and a new bpftrace backend was added for Linux CI alongside the existing SystemTap tests. Line probe tests were removed since that probe was never restored after 3.11.
This commit is contained in:
parent
8c796782fc
commit
9a268e3e33
15 changed files with 319 additions and 60 deletions
|
|
@ -1568,6 +1568,7 @@ dummy_func(
|
|||
DEAD(retval);
|
||||
SAVE_STACK();
|
||||
assert(STACK_LEVEL() == 0);
|
||||
DTRACE_FUNCTION_RETURN();
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
// GH-99729: We need to unlink the frame *before* clearing it:
|
||||
_PyInterpreterFrame *dying = frame;
|
||||
|
|
@ -1760,6 +1761,7 @@ dummy_func(
|
|||
_PyStackRef temp = retval;
|
||||
DEAD(retval);
|
||||
SAVE_STACK();
|
||||
DTRACE_FUNCTION_RETURN();
|
||||
tstate->exc_info = gen->gi_exc_state.previous_item;
|
||||
gen->gi_exc_state.previous_item = NULL;
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
|
|
@ -4569,6 +4571,7 @@ dummy_func(
|
|||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP(0);
|
||||
DTRACE_FUNCTION_ENTRY();
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
|
||||
|
|
@ -6469,6 +6472,12 @@ dummy_func(
|
|||
}
|
||||
|
||||
spilled label(exit_unwind) {
|
||||
assert(_PyErr_Occurred(tstate));
|
||||
DTRACE_FUNCTION_RETURN();
|
||||
goto exit_unwind_notrace;
|
||||
}
|
||||
|
||||
spilled label(exit_unwind_notrace) {
|
||||
assert(_PyErr_Occurred(tstate));
|
||||
_Py_LeaveRecursiveCallPy(tstate);
|
||||
assert(frame->owner != FRAME_OWNED_BY_INTERPRETER);
|
||||
|
|
@ -6501,8 +6510,9 @@ dummy_func(
|
|||
spilled label(start_frame) {
|
||||
int too_deep = _Py_EnterRecursivePy(tstate);
|
||||
if (too_deep) {
|
||||
goto exit_unwind;
|
||||
goto exit_unwind_notrace;
|
||||
}
|
||||
DTRACE_FUNCTION_ENTRY();
|
||||
next_instr = frame->instr_ptr;
|
||||
#ifdef Py_DEBUG
|
||||
int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS());
|
||||
|
|
@ -6601,6 +6611,7 @@ dummy_func(
|
|||
error:
|
||||
exception_unwind:
|
||||
exit_unwind:
|
||||
exit_unwind_notrace:
|
||||
handle_eval_breaker:
|
||||
resume_frame:
|
||||
start_frame:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue