summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2022-07-08 13:25:53 (GMT)
committerGitHub <noreply@github.com>2022-07-08 13:25:53 (GMT)
commit36a3372d5105ffbd083a56cc8442a81a5bfeb19b (patch)
tree2966ac6e07dd2bc80605cb707c0e76a8ef75b2c4
parent73a1800b55bc018cb2ac2a38c49e368bfe4a98d4 (diff)
downloadcpython-36a3372d5105ffbd083a56cc8442a81a5bfeb19b.zip
cpython-36a3372d5105ffbd083a56cc8442a81a5bfeb19b.tar.gz
cpython-36a3372d5105ffbd083a56cc8442a81a5bfeb19b.tar.bz2
[3.11] gh-94215: Fix error handling for line-tracing events (GH-94681) (GH-94688)
* Re-enable crasher * Fix error handling for line-tracing events * blurb add (cherry picked from commit 23ee4a8067506e6c9c47748185653617413f7a60) Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
-rw-r--r--Lib/test/test_pdb.py1
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2022-07-07-21-13-25.gh-issue-94215._Sv9Ms.rst3
-rw-r--r--Python/ceval.c19
3 files changed, 17 insertions, 6 deletions
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 968a32f..55c3283 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -2085,7 +2085,6 @@ def bœr():
expected = '(Pdb) The correct file was executed'
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
- @unittest.skip("test crashes, see gh-94215")
def test_gh_94215_crash(self):
script = """\
def func():
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-07-07-21-13-25.gh-issue-94215._Sv9Ms.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-07-21-13-25.gh-issue-94215._Sv9Ms.rst
new file mode 100644
index 0000000..07af472
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-07-21-13-25.gh-issue-94215._Sv9Ms.rst
@@ -0,0 +1,3 @@
+Fix an issue where exceptions raised by line-tracing events would cause
+frames to be left in an invalid state, possibly resulting in a hard crash of
+the interpreter.
diff --git a/Python/ceval.c b/Python/ceval.c
index 32f471f..1a54545 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5642,16 +5642,25 @@ handle_eval_breaker:
err = maybe_call_line_trace(tstate->c_tracefunc,
tstate->c_traceobj,
tstate, frame, instr_prev);
+ // Reload possibly changed frame fields:
+ stack_pointer = _PyFrame_GetStackPointer(frame);
+ frame->stacktop = -1;
+ // next_instr is only reloaded if tracing *does not* raise.
+ // This is consistent with the behavior of older Python
+ // versions. If a trace function sets a new f_lineno and
+ // *then* raises, we use the *old* location when searching
+ // for an exception handler, displaying the traceback, and
+ // so on:
if (err) {
- /* trace function raised an exception */
+ // next_instr wasn't incremented at the start of this
+ // instruction. Increment it before handling the error,
+ // so that it looks the same as a "normal" instruction:
next_instr++;
goto error;
}
- /* Reload possibly changed frame fields */
+ // Reload next_instr. Don't increment it, though, since
+ // we're going to re-dispatch to the "true" instruction now:
next_instr = frame->prev_instr;
-
- stack_pointer = _PyFrame_GetStackPointer(frame);
- frame->stacktop = -1;
}
}
}