diff options
author | Mark Shannon <mark@hotpy.org> | 2021-07-08 18:21:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-08 18:21:22 (GMT) |
commit | 9f2c63b258846a95393b556fee5e1090173ea717 (patch) | |
tree | d6103597f2f3dfda5ee49134c74c4249220fe307 /Python/ceval.c | |
parent | 61eb9b5dfd919ba5d1ec9f7df0137f2e6d196972 (diff) | |
download | cpython-9f2c63b258846a95393b556fee5e1090173ea717.zip cpython-9f2c63b258846a95393b556fee5e1090173ea717.tar.gz cpython-9f2c63b258846a95393b556fee5e1090173ea717.tar.bz2 |
bpo-44570: Fix line tracing for forward jumps to duplicated tails (GH-27067)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 25548e3..2674e46 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -35,7 +35,6 @@ typedef struct { PyCodeObject *code; // The code object for the bounds. May be NULL. - int instr_prev; // Only valid if code != NULL. PyCodeAddressRange bounds; // Only valid if code != NULL. CFrame cframe; } PyTraceInfo; @@ -78,8 +77,8 @@ static void call_exc_trace(Py_tracefunc, PyObject *, PyTraceInfo *trace_info); static int maybe_call_line_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, - PyTraceInfo *); -static void maybe_dtrace_line(PyFrameObject *, PyTraceInfo *); + PyTraceInfo *, int); +static void maybe_dtrace_line(PyFrameObject *, PyTraceInfo *, int); static void dtrace_function_entry(PyFrameObject *); static void dtrace_function_return(PyFrameObject *); @@ -1781,11 +1780,13 @@ main_loop: } tracing_dispatch: + { + int instr_prev = f->f_lasti; f->f_lasti = INSTR_OFFSET(); NEXTOPARG(); if (PyDTrace_LINE_ENABLED()) - maybe_dtrace_line(f, &trace_info); + maybe_dtrace_line(f, &trace_info, instr_prev); /* line-by-line tracing support */ @@ -1799,7 +1800,7 @@ main_loop: err = maybe_call_line_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f, - &trace_info); + &trace_info, instr_prev); /* Reload possibly changed frame fields */ JUMPTO(f->f_lasti); stack_pointer = f->f_valuestack+f->f_stackdepth; @@ -1810,6 +1811,7 @@ main_loop: } NEXTOPARG(); } + } #ifdef LLTRACE /* Instruction tracing */ @@ -4502,9 +4504,6 @@ exception_unwind: PUSH(val); PUSH(exc); JUMPTO(handler); - if (trace_info.cframe.use_tracing) { - trace_info.instr_prev = INT_MAX; - } /* Resume normal execution */ f->f_state = FRAME_EXECUTING; goto main_loop; @@ -5455,7 +5454,6 @@ initialize_trace_info(PyTraceInfo *trace_info, PyFrameObject *frame) { if (trace_info->code != frame->f_code) { trace_info->code = frame->f_code; - trace_info->instr_prev = -1; _PyCode_InitAddressRange(frame->f_code, &trace_info->bounds); } } @@ -5507,7 +5505,7 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, PyThreadState *tstate, PyFrameObject *frame, - PyTraceInfo *trace_info) + PyTraceInfo *trace_info, int instr_prev) { int result = 0; @@ -5516,13 +5514,11 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, then call the trace function if we're tracing source lines. */ initialize_trace_info(trace_info, frame); - int lastline = trace_info->bounds.ar_line; + int lastline = _PyCode_CheckLineNumber(instr_prev*2, &trace_info->bounds); int line = _PyCode_CheckLineNumber(frame->f_lasti*2, &trace_info->bounds); if (line != -1 && frame->f_trace_lines) { - /* Trace backward edges or first instruction of a new line */ - if (frame->f_lasti < trace_info->instr_prev || - (line != lastline && frame->f_lasti*2 == trace_info->bounds.ar_start)) - { + /* Trace backward edges or if line number has changed */ + if (frame->f_lasti < instr_prev || line != lastline) { result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_LINE, Py_None); } } @@ -5530,7 +5526,6 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, if (frame->f_trace_opcodes) { result = call_trace(func, obj, tstate, frame, trace_info, PyTrace_OPCODE, Py_None); } - trace_info->instr_prev = frame->f_lasti; return result; } @@ -6475,7 +6470,7 @@ dtrace_function_return(PyFrameObject *f) /* DTrace equivalent of maybe_call_line_trace. */ static void maybe_dtrace_line(PyFrameObject *frame, - PyTraceInfo *trace_info) + PyTraceInfo *trace_info, int instr_prev) { const char *co_filename, *co_name; @@ -6487,7 +6482,7 @@ maybe_dtrace_line(PyFrameObject *frame, /* 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 (line != frame->f_lineno || frame->f_lasti < trace_info->instr_prev) { + if (line != frame->f_lineno || frame->f_lasti < instr_prev) { if (line != -1) { frame->f_lineno = line; co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename); @@ -6499,7 +6494,6 @@ maybe_dtrace_line(PyFrameObject *frame, PyDTrace_LINE(co_filename, co_name, line); } } - trace_info->instr_prev = frame->f_lasti; } |