Skip to content

Commit 7fd92a8

Browse files
authored
bpo-45813: Make sure that frame->generator is NULLed when generator is deallocated. (GH-29700)
1 parent d9cedab commit 7fd92a8

File tree

4 files changed

+12
-0
lines changed

4 files changed

+12
-0
lines changed

Lib/test/test_coroutines.py

+7
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,13 @@ async def run_gen():
21912191
return 'end'
21922192
self.assertEqual(run_async(run_gen()), ([], 'end'))
21932193

2194+
def test_bpo_45813(self):
2195+
'This would crash the interpreter in 3.11a2'
2196+
async def f():
2197+
pass
2198+
frame = f().cr_frame
2199+
frame.clear()
2200+
21942201

21952202
class CoroAsyncIOCompatTest(unittest.TestCase):
21962203

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix crash when calling coro.cr_frame.clear() after coroutine has been freed.

Objects/genobject.c

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ gen_dealloc(PyGenObject *gen)
134134
InterpreterFrame *frame = gen->gi_xframe;
135135
if (frame != NULL) {
136136
gen->gi_xframe = NULL;
137+
frame->generator = NULL;
137138
frame->previous = NULL;
138139
_PyFrame_Clear(frame, 1);
139140
}

Python/frame.c

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ take_ownership(PyFrameObject *f, InterpreterFrame *frame)
9999
int
100100
_PyFrame_Clear(InterpreterFrame * frame, int take)
101101
{
102+
/* It is the responsibility of the owning generator/coroutine
103+
* to have cleared the generator pointer */
104+
assert(frame->generator == NULL);
102105
if (frame->frame_obj) {
103106
PyFrameObject *f = frame->frame_obj;
104107
frame->frame_obj = NULL;

0 commit comments

Comments
 (0)