diff options
author | Tian Gao <gaogaotiantian@hotmail.com> | 2024-03-12 23:35:28 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-12 23:35:28 (GMT) |
commit | a53cc3f49463e50cb3e2b839b3a82e6bf7f73fee (patch) | |
tree | e663c9885c01a420ba465dc08259b62abd272228 /Python | |
parent | 149f7f7ae28944579792d22607532006977177c9 (diff) | |
download | cpython-a53cc3f49463e50cb3e2b839b3a82e6bf7f73fee.zip cpython-a53cc3f49463e50cb3e2b839b3a82e6bf7f73fee.tar.gz cpython-a53cc3f49463e50cb3e2b839b3a82e6bf7f73fee.tar.bz2 |
GH-116098: Remove dead frame object creation code (GH-116687)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/frame.c | 27 |
1 files changed, 9 insertions, 18 deletions
diff --git a/Python/frame.c b/Python/frame.c index ddf6ef6..f88a8f0 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -37,24 +37,15 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) return NULL; } PyErr_SetRaisedException(exc); - if (frame->frame_obj) { - // GH-97002: How did we get into this horrible situation? Most likely, - // allocating f triggered a GC collection, which ran some code that - // *also* created the same frame... while we were in the middle of - // creating it! See test_sneaky_frame_object in test_frame.py for a - // concrete example. - // - // Regardless, just throw f away and use that frame instead, since it's - // already been exposed to user code. It's actually a bit tricky to do - // this, since we aren't backed by a real _PyInterpreterFrame anymore. - // Just pretend that we have an owned, cleared frame so frame_dealloc - // doesn't make the situation worse: - f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; - f->f_frame->owner = FRAME_CLEARED; - f->f_frame->frame_obj = f; - Py_DECREF(f); - return frame->frame_obj; - } + + // GH-97002: There was a time when a frame object could be created when we + // are allocating the new frame object f above, so frame->frame_obj would + // be assigned already. That path does not exist anymore. We won't call any + // Python code in this function and garbage collection will not run. + // Notice that _PyFrame_New_NoTrack() can potentially raise a MemoryError, + // but it won't allocate a traceback until the frame unwinds, so we are safe + // here. + assert(frame->frame_obj == NULL); assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); assert(frame->owner != FRAME_CLEARED); f->f_frame = frame; |