summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-07-08 18:21:09 (GMT)
committerGitHub <noreply@github.com>2021-07-08 18:21:09 (GMT)
commitda6414f0acf5ec9ea3b07e4b3907bc49c2a61e2f (patch)
tree17309f8d48ae702110150f9d9c9731c8810905e0
parent91a8f8c16ca9a7e2466a8241d9b41769ef97d094 (diff)
downloadcpython-da6414f0acf5ec9ea3b07e4b3907bc49c2a61e2f.zip
cpython-da6414f0acf5ec9ea3b07e4b3907bc49c2a61e2f.tar.gz
cpython-da6414f0acf5ec9ea3b07e4b3907bc49c2a61e2f.tar.bz2
bpo-44570: Fix line tracing for forwards jumps to duplicated tails (GH-27068)
-rw-r--r--Lib/test/test_sys_settrace.py35
-rw-r--r--Python/ceval.c6
2 files changed, 37 insertions, 4 deletions
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
index 5f2b908..c42c69d 100644
--- a/Lib/test/test_sys_settrace.py
+++ b/Lib/test/test_sys_settrace.py
@@ -1041,6 +1041,41 @@ class TraceTestCase(unittest.TestCase):
(-8, 'return'),
(1, 'return')])
+ def test_flow_converges_on_same_line(self):
+
+ def foo(x):
+ if x:
+ try:
+ 1/(x - 1)
+ except ZeroDivisionError:
+ pass
+ return x
+
+ def func():
+ for i in range(2):
+ foo(i)
+
+ self.run_and_compare(func,
+ [(0, 'call'),
+ (1, 'line'),
+ (2, 'line'),
+ (-8, 'call'),
+ (-7, 'line'),
+ (-2, 'line'),
+ (-2, 'return'),
+ (1, 'line'),
+ (2, 'line'),
+ (-8, 'call'),
+ (-7, 'line'),
+ (-6, 'line'),
+ (-5, 'line'),
+ (-5, 'exception'),
+ (-4, 'line'),
+ (-3, 'line'),
+ (-2, 'line'),
+ (-2, 'return'),
+ (1, 'line'),
+ (1, 'return')])
class SkipLineEventsTraceTestCase(TraceTestCase):
"""Repeat the trace tests, but with per-line events skipped"""
diff --git a/Python/ceval.c b/Python/ceval.c
index 611a39d..2218405 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5476,10 +5476,8 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
int lastline = _PyCode_CheckLineNumber(instr_prev*2, &tstate->trace_info.bounds);
int line = _PyCode_CheckLineNumber(frame->f_lasti*2, &tstate->trace_info.bounds);
if (line != -1 && frame->f_trace_lines) {
- /* Trace backward edges or first instruction of a new line */
- if (frame->f_lasti < instr_prev ||
- (line != lastline && frame->f_lasti*2 == tstate->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, PyTrace_LINE, Py_None);
}
}