Skip to content

Commit

Permalink
pythongh-94215: Fix reference count issue in exception_unwind
Browse files Browse the repository at this point in the history
Zero-cost exception handling did not take ``frame_setlineno()`` into
account. It can pop off stacks. This can lead to a crash.

Exception unwinding now re-calculates the stack pointer.

Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
  • Loading branch information
tiran and iritkatriel committed Jul 7, 2022
1 parent 7169766 commit 968d0ba
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,7 @@ def test_issue42383(self):
expected = '(Pdb) The correct file was executed'
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)

@unittest.skip("test crashes, see gh-94215")
# @unittest.skip("test crashes, see gh-94215")
def test_gh_94215_crash(self):
script = """\
def func():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix a reference counting bug in exception unwinding code for zero-cost
exception handling. The code did not take into account that
``frame_setlineno()`` can pop off stacks, too.
Patch by Irit Katriel and Christian Heimes.
5 changes: 5 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -5795,6 +5795,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int

/* Pop remaining stack entries. */
PyObject **stackbase = _PyFrame_Stackbase(frame);
if (frame->stacktop != -1) {
// frame_setlineno() may have popped off additional stacks in
// frame_stack_pop(). Re-calculate stack pointer.
stack_pointer = _PyFrame_GetStackPointer(frame);
}
while (stack_pointer > stackbase) {
PyObject *o = POP();
Py_XDECREF(o);
Expand Down

0 comments on commit 968d0ba

Please sign in to comment.