bpo-31344: Per-frame control of trace events (GH-3417)
f_trace_lines: enable/disable line trace events
f_trace_opcodes: enable/disable opcode trace events
These are intended primarily for testing of the interpreter
itself, as they make it much easier to emulate signals
arriving at unfortunate times.
diff --git a/Python/ceval.c b/Python/ceval.c
index 8fc65cd..a072a5f 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4458,12 +4458,19 @@
*instr_lb = bounds.ap_lower;
*instr_ub = bounds.ap_upper;
}
- /* If the last instruction falls at the start of a line or if
- it represents a jump backwards, update the frame's line
- number and call the trace function. */
- if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
+ /* Always emit an opcode event if we're tracing all opcodes. */
+ if (frame->f_trace_opcodes) {
+ result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None);
+ }
+ /* If the last instruction falls at the start of a line or if it
+ represents a jump backwards, update the frame's line number and
+ then call the trace function if we're tracing source lines.
+ */
+ if ((frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev)) {
frame->f_lineno = line;
- result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None);
+ if (frame->f_trace_lines) {
+ result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None);
+ }
}
*instr_prev = frame->f_lasti;
return result;