summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2022-09-19 21:02:24 (GMT)
committerGitHub <noreply@github.com>2022-09-19 21:02:24 (GMT)
commitc10e33ac119d96c4d88d5ae8b59e65a76ae0ad3c (patch)
treed98d4b9a2cb0fae394a301c79bfdb73a86f0cb2a
parent5b3a2569f4b4dfb58a8f90a241f9dac1a7ea4bf6 (diff)
downloadcpython-c10e33ac119d96c4d88d5ae8b59e65a76ae0ad3c.zip
cpython-c10e33ac119d96c4d88d5ae8b59e65a76ae0ad3c.tar.gz
cpython-c10e33ac119d96c4d88d5ae8b59e65a76ae0ad3c.tar.bz2
GH-96864: Check for error between line and opcode events (GH-96880)
-rw-r--r--Lib/test/test_sys_settrace.py14
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-09-16-12-36-13.gh-issue-96864.PLU3i8.rst2
-rw-r--r--Python/ceval.c2
3 files changed, 17 insertions, 1 deletions
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
index 9f1aa81..aa61f8b1 100644
--- a/Lib/test/test_sys_settrace.py
+++ b/Lib/test/test_sys_settrace.py
@@ -1721,6 +1721,20 @@ class RaisingTraceFuncTestCase(unittest.TestCase):
finally:
sys.settrace(existing)
+ def test_line_event_raises_before_opcode_event(self):
+ exception = ValueError("BOOM!")
+ def trace(frame, event, arg):
+ if event == "line":
+ raise exception
+ frame.f_trace_opcodes = True
+ return trace
+ def f():
+ pass
+ with self.assertRaises(ValueError) as caught:
+ sys.settrace(trace)
+ f()
+ self.assertIs(caught.exception, exception)
+
# 'Jump' tests: assigning to frame.f_lineno within a trace function
# moves the execution position - it's how debuggers implement a Jump
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-16-12-36-13.gh-issue-96864.PLU3i8.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-16-12-36-13.gh-issue-96864.PLU3i8.rst
new file mode 100644
index 0000000..c0d41ae
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-16-12-36-13.gh-issue-96864.PLU3i8.rst
@@ -0,0 +1,2 @@
+Fix a possible assertion failure, fatal error, or :exc:`SystemError` if a
+line tracing event raises an exception while opcode tracing is enabled.
diff --git a/Python/ceval.c b/Python/ceval.c
index 8891d6c..a07fb49 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -6293,7 +6293,7 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
}
}
/* Always emit an opcode event if we're tracing all opcodes. */
- if (f->f_trace_opcodes) {
+ if (f->f_trace_opcodes && result == 0) {
result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None);
}
return result;