Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 23ee4a8

Browse filesBrowse files
authored
gh-94215: Fix error handling for line-tracing events (GH-94681)
* Re-enable crasher * Fix error handling for line-tracing events * blurb add
1 parent e5b841a commit 23ee4a8
Copy full SHA for 23ee4a8

File tree

Expand file treeCollapse file tree

3 files changed

+17
-6
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+17
-6
lines changed

‎Lib/test/test_pdb.py

Copy file name to clipboardExpand all lines: Lib/test/test_pdb.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2085,7 +2085,6 @@ def test_issue42383(self):
20852085
expected = '(Pdb) The correct file was executed'
20862086
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
20872087

2088-
@unittest.skip("test crashes, see gh-94215")
20892088
def test_gh_94215_crash(self):
20902089
script = """\
20912090
def func():
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix an issue where exceptions raised by line-tracing events would cause
2+
frames to be left in an invalid state, possibly resulting in a hard crash of
3+
the interpreter.

‎Python/ceval.c

Copy file name to clipboardExpand all lines: Python/ceval.c
+14-5Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5683,16 +5683,25 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
56835683
err = maybe_call_line_trace(tstate->c_tracefunc,
56845684
tstate->c_traceobj,
56855685
tstate, frame, instr_prev);
5686+
// Reload possibly changed frame fields:
5687+
stack_pointer = _PyFrame_GetStackPointer(frame);
5688+
frame->stacktop = -1;
5689+
// next_instr is only reloaded if tracing *does not* raise.
5690+
// This is consistent with the behavior of older Python
5691+
// versions. If a trace function sets a new f_lineno and
5692+
// *then* raises, we use the *old* location when searching
5693+
// for an exception handler, displaying the traceback, and
5694+
// so on:
56865695
if (err) {
5687-
/* trace function raised an exception */
5696+
// next_instr wasn't incremented at the start of this
5697+
// instruction. Increment it before handling the error,
5698+
// so that it looks the same as a "normal" instruction:
56885699
next_instr++;
56895700
goto error;
56905701
}
5691-
/* Reload possibly changed frame fields */
5702+
// Reload next_instr. Don't increment it, though, since
5703+
// we're going to re-dispatch to the "true" instruction now:
56925704
next_instr = frame->prev_instr;
5693-
5694-
stack_pointer = _PyFrame_GetStackPointer(frame);
5695-
frame->stacktop = -1;
56965705
}
56975706
}
56985707
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.