mirror of
https://github.com/python/cpython.git
synced 2025-12-07 17:57:56 +00:00
bpo-39114: Fix tracing of except handlers with name binding (GH-17769)
When producing the bytecode of exception handlers with name binding (like `except Exception as e`) we need to produce a try-finally block to make sure that the name is deleted after the handler is executed to prevent cycles in the stack frame objects. The bytecode associated with this try-finally block does not have source lines associated and it was causing problems when the tracing functionality was running over it.
This commit is contained in:
parent
149175c6df
commit
04ec7a1f7a
3 changed files with 50 additions and 1 deletions
|
|
@ -481,6 +481,51 @@ class TraceTestCase(unittest.TestCase):
|
||||||
[(0, 'call'),
|
[(0, 'call'),
|
||||||
(1, 'line')])
|
(1, 'line')])
|
||||||
|
|
||||||
|
def test_18_except_with_name(self):
|
||||||
|
def func():
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
raise Exception
|
||||||
|
except Exception as e:
|
||||||
|
raise
|
||||||
|
x = "Something"
|
||||||
|
y = "Something"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.run_and_compare(func,
|
||||||
|
[(0, 'call'),
|
||||||
|
(1, 'line'),
|
||||||
|
(2, 'line'),
|
||||||
|
(3, 'line'),
|
||||||
|
(3, 'exception'),
|
||||||
|
(4, 'line'),
|
||||||
|
(5, 'line'),
|
||||||
|
(8, 'line'),
|
||||||
|
(9, 'line'),
|
||||||
|
(9, 'return')])
|
||||||
|
|
||||||
|
def test_19_except_with_finally(self):
|
||||||
|
def func():
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
raise Exception
|
||||||
|
finally:
|
||||||
|
y = "Something"
|
||||||
|
except Exception:
|
||||||
|
b = 23
|
||||||
|
|
||||||
|
self.run_and_compare(func,
|
||||||
|
[(0, 'call'),
|
||||||
|
(1, 'line'),
|
||||||
|
(2, 'line'),
|
||||||
|
(3, 'line'),
|
||||||
|
(3, 'exception'),
|
||||||
|
(5, 'line'),
|
||||||
|
(6, 'line'),
|
||||||
|
(7, 'line'),
|
||||||
|
(7, 'return')])
|
||||||
|
|
||||||
|
|
||||||
class SkipLineEventsTraceTestCase(TraceTestCase):
|
class SkipLineEventsTraceTestCase(TraceTestCase):
|
||||||
"""Repeat the trace tests, but with per-line events skipped"""
|
"""Repeat the trace tests, but with per-line events skipped"""
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix incorrent line execution reporting in trace functions when tracing
|
||||||
|
exception handlers with name binding. Patch by Pablo Galindo.
|
||||||
|
|
@ -3610,7 +3610,9 @@ exception_unwind:
|
||||||
PUSH(val);
|
PUSH(val);
|
||||||
PUSH(exc);
|
PUSH(exc);
|
||||||
JUMPTO(handler);
|
JUMPTO(handler);
|
||||||
if (_Py_TracingPossible(ceval)) {
|
if (_Py_TracingPossible(ceval) &&
|
||||||
|
((f->f_lasti < instr_lb || f->f_lasti >= instr_ub) ||
|
||||||
|
!(f->f_lasti == instr_lb || f->f_lasti < instr_prev))) {
|
||||||
/* Make sure that we trace line after exception */
|
/* Make sure that we trace line after exception */
|
||||||
instr_prev = INT_MAX;
|
instr_prev = INT_MAX;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue