From 04ec7a1f7a5b92187a73cd02670958444c6f2220 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 2 Jan 2020 11:38:44 +0000 Subject: [PATCH] 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. --- Lib/test/test_sys_settrace.py | 45 +++++++++++++++++++ .../2019-12-31-18-25-45.bpo-39114.WG9alt.rst | 2 + Python/ceval.c | 4 +- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-12-31-18-25-45.bpo-39114.WG9alt.rst diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 0af015aa56bb4d..a0d1122fad83be 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -481,6 +481,51 @@ def func(): [(0, 'call'), (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): """Repeat the trace tests, but with per-line events skipped""" diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-12-31-18-25-45.bpo-39114.WG9alt.rst b/Misc/NEWS.d/next/Core and Builtins/2019-12-31-18-25-45.bpo-39114.WG9alt.rst new file mode 100644 index 00000000000000..d742af9d3262ea --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-12-31-18-25-45.bpo-39114.WG9alt.rst @@ -0,0 +1,2 @@ +Fix incorrent line execution reporting in trace functions when tracing +exception handlers with name binding. Patch by Pablo Galindo. diff --git a/Python/ceval.c b/Python/ceval.c index 96ed329b0d9952..bd9454b2812ddf 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3610,7 +3610,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) PUSH(val); PUSH(exc); 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 */ instr_prev = INT_MAX; }