Skip to content

Commit

Permalink
bpo-45813: Make sure that frame->generator is NULLed when generator i…
Browse files Browse the repository at this point in the history
…s deallocated. (GH-29700)
  • Loading branch information
markshannon authored Nov 22, 2021
1 parent d9cedab commit 7fd92a8
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -2191,6 +2191,13 @@ async def run_gen():
return 'end'
self.assertEqual(run_async(run_gen()), ([], 'end'))

def test_bpo_45813(self):
'This would crash the interpreter in 3.11a2'
async def f():
pass
frame = f().cr_frame
frame.clear()


class CoroAsyncIOCompatTest(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash when calling coro.cr_frame.clear() after coroutine has been freed.
1 change: 1 addition & 0 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ gen_dealloc(PyGenObject *gen)
InterpreterFrame *frame = gen->gi_xframe;
if (frame != NULL) {
gen->gi_xframe = NULL;
frame->generator = NULL;
frame->previous = NULL;
_PyFrame_Clear(frame, 1);
}
Expand Down
3 changes: 3 additions & 0 deletions Python/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ take_ownership(PyFrameObject *f, InterpreterFrame *frame)
int
_PyFrame_Clear(InterpreterFrame * frame, int take)
{
/* It is the responsibility of the owning generator/coroutine
* to have cleared the generator pointer */
assert(frame->generator == NULL);
if (frame->frame_obj) {
PyFrameObject *f = frame->frame_obj;
frame->frame_obj = NULL;
Expand Down

0 comments on commit 7fd92a8

Please sign in to comment.