diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2022-12-06 17:02:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-06 17:02:19 (GMT) |
commit | 2182a71eedbc8e95c3cf2d8c0aa2fd66c7a93db4 (patch) | |
tree | 07a441ad880a7e112578a6ae6f3f0b95e67cd014 /Python/ceval.c | |
parent | 3fae04b10e2655a20a3aadb5e0d63e87206d0c67 (diff) | |
download | cpython-2182a71eedbc8e95c3cf2d8c0aa2fd66c7a93db4.zip cpython-2182a71eedbc8e95c3cf2d8c0aa2fd66c7a93db4.tar.gz cpython-2182a71eedbc8e95c3cf2d8c0aa2fd66c7a93db4.tar.bz2 |
[3.11] GH-99729: Unlink frames before clearing them (#100047)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 8cbe838..a34e4ff 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1617,14 +1617,6 @@ trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject return 0; } -static _PyInterpreterFrame * -pop_frame(PyThreadState *tstate, _PyInterpreterFrame *frame) -{ - _PyInterpreterFrame *prev_frame = frame->previous; - _PyEvalFrameClearAndPop(tstate, frame); - return prev_frame; -} - /* It is only between the PRECALL instruction and the following CALL, * that this has any meaning. */ @@ -2441,7 +2433,10 @@ handle_eval_breaker: DTRACE_FUNCTION_EXIT(); _Py_LeaveRecursiveCallTstate(tstate); if (!frame->is_entry) { - frame = cframe.current_frame = pop_frame(tstate, frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); _PyFrame_StackPush(frame, retval); goto resume_frame; } @@ -5833,7 +5828,10 @@ exit_unwind: assert(tstate->cframe->current_frame == frame->previous); return NULL; } - frame = cframe.current_frame = pop_frame(tstate, frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); resume_with_error: SET_LOCALS_FROM_FRAME(); |