From 13825a11461ffd9ea8cc38f0d890e275cec4562d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 11 Aug 2022 10:58:30 +0100 Subject: [PATCH 1/5] Add failing test for issue 95818. --- Lib/test/test_frame.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index a715e725a7e45b1..e82456871a3ecbf 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -3,6 +3,7 @@ import types import unittest import weakref +from test.support.os_helper import TESTFN from test import support @@ -235,6 +236,27 @@ def inner(): r"^$" % (file_repr, offset + 5)) +class TestIncompleteFrameAreInvisible(unittest.TestCase): + + def test_issue95818(self): + #See GH-95818 for details + import gc + 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() From e42f6fd952cee8f0eae494d8faca39301079d880 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 11 Aug 2022 10:59:47 +0100 Subject: [PATCH 2/5] Skip incomplete frames in PyThreadState_GetFrame(). --- Python/pystate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Python/pystate.c b/Python/pystate.c index 11cc122185f781f..bcdb825a8629b0c 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -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(); } From 229f671fe2e8ad320698b551dee735d35c1e2db8 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 11 Aug 2022 11:02:07 +0100 Subject: [PATCH 3/5] Add news --- .../2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst new file mode 100644 index 000000000000000..1e243f5614f1ca8 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-08-11-11-01-56.gh-issue-95818.iClLdl.rst @@ -0,0 +1 @@ +Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`. From 865e06ed00c223714f3698fa2d70c1242d4cf46f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 11 Aug 2022 11:04:38 +0100 Subject: [PATCH 4/5] Remove unneeded import. --- Lib/test/test_frame.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index e82456871a3ecbf..404d40ed0f2fb6a 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -3,7 +3,6 @@ import types import unittest import weakref -from test.support.os_helper import TESTFN from test import support From ffbbdaa72592da7d2a02c35f558cd6cbf0729998 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 11 Aug 2022 12:24:12 +0100 Subject: [PATCH 5/5] Cleanup after test --- Lib/test/test_frame.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 404d40ed0f2fb6a..9fab17684eec02b 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -240,8 +240,9 @@ class TestIncompleteFrameAreInvisible(unittest.TestCase): def test_issue95818(self): #See GH-95818 for details import gc - gc.set_threshold(1,1,1) + self.addCleanup(gc.set_threshold, *gc.get_threshold()) + gc.set_threshold(1,1,1) class GCHello: def __del__(self): print("Destroyed from gc")