GH-95818: Skip incomplete frames in `PyThreadState_GetFrame` (GH-95886)

This commit is contained in:
Mark Shannon 2022-08-11 14:06:32 +01:00 committed by GitHub
parent 23a757f44f
commit 1b46d118e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 2 deletions

View File

@ -235,6 +235,28 @@ class ReprTest(unittest.TestCase):
r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code inner>$"
% (file_repr, offset + 5))
class TestIncompleteFrameAreInvisible(unittest.TestCase):
def test_issue95818(self):
#See GH-95818 for details
import gc
self.addCleanup(gc.set_threshold, *gc.get_threshold())
gc.set_threshold(1,1,1)
class GCHello:
def __del__(self):
print("Destroyed from gc")
def gen():
yield
fd = open(__file__)
l = [fd, GCHello()]
l.append(l)
del fd
del l
gen()
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1 @@
Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`.

View File

@ -1255,10 +1255,14 @@ PyFrameObject*
PyThreadState_GetFrame(PyThreadState *tstate)
{
assert(tstate != NULL);
if (tstate->cframe->current_frame == NULL) {
_PyInterpreterFrame *f = tstate->cframe->current_frame;
while (f && _PyFrame_IsIncomplete(f)) {
f = f->previous;
}
if (f == NULL) {
return NULL;
}
PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->cframe->current_frame);
PyFrameObject *frame = _PyFrame_GetFrameObject(f);
if (frame == NULL) {
PyErr_Clear();
}