[3.12] gh-58956: Fix a frame refleak in bdb (GH-128190) (#128953)
https://github.com/python/cpython/commit/f45da82c11a0fcbc28c099af27e47806f53... commit: f45da82c11a0fcbc28c099af27e47806f530a97b branch: 3.12 author: Tian Gao <gaogaotiantian@hotmail.com> committer: gaogaotiantian <gaogaotiantian@hotmail.com> date: 2025-01-17T14:19:37-05:00 summary: [3.12] gh-58956: Fix a frame refleak in bdb (GH-128190) (#128953) * [3.12] gh-58956: Fix a frame refleak in bdb (GH-128190) (cherry picked from commit 767c89ba7c5a70626df6e75eb56b546bf911b997) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com> files: A Misc/NEWS.d/next/Library/2024-12-23-02-09-44.gh-issue-58956.4OdMdT.rst M Lib/bdb.py M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Lib/bdb.py b/Lib/bdb.py index 196e6b178cb9fd..3486deacd86a7c 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -340,6 +340,7 @@ def set_trace(self, frame=None): self.botframe = frame frame = frame.f_back self.set_step() + self.enterframe = None sys.settrace(self.trace_dispatch) def set_continue(self): @@ -356,6 +357,7 @@ def set_continue(self): while frame and frame is not self.botframe: del frame.f_trace frame = frame.f_back + self.enterframe = None def set_quit(self): """Set quitting attribute to True. diff --git a/Lib/pdb.py b/Lib/pdb.py index 1e1b5ea4f0a184..2a6e994dac1073 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -281,6 +281,7 @@ def forget(self): if hasattr(self, 'curframe') and self.curframe: self.curframe.f_globals.pop('__pdb_convenience_variables', None) self.curframe = None + self.curframe_locals = {} self.tb_lineno.clear() def setup(self, f, tb): diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index bd61de0ad3494c..778aa03a63ab63 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1981,6 +1981,58 @@ def test_pdb_ambiguous_statements(): (Pdb) continue """ +def test_pdb_frame_refleak(): + """ + pdb should not leak reference to frames + + >>> def frame_leaker(container): + ... import sys + ... container.append(sys._getframe()) + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... pass + + >>> def test_function(): + ... import gc + ... container = [] + ... frame_leaker(container) # c + ... print(len(gc.get_referrers(container[0]))) + ... container = [] + ... frame_leaker(container) # n c + ... print(len(gc.get_referrers(container[0]))) + ... container = [] + ... frame_leaker(container) # r c + ... print(len(gc.get_referrers(container[0]))) + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue', + ... 'next', + ... 'continue', + ... 'return', + ... 'continue', + ... ]): + ... test_function() + > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker() + -> pass + (Pdb) continue + 1 + > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker() + -> pass + (Pdb) next + --Return-- + > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()->None + -> pass + (Pdb) continue + 1 + > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker() + -> pass + (Pdb) return + --Return-- + > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()->None + -> pass + (Pdb) continue + 1 + """ + def test_pdb_issue_gh_65052(): """See GH-65052 diff --git a/Misc/NEWS.d/next/Library/2024-12-23-02-09-44.gh-issue-58956.4OdMdT.rst b/Misc/NEWS.d/next/Library/2024-12-23-02-09-44.gh-issue-58956.4OdMdT.rst new file mode 100644 index 00000000000000..b78bc5aaf44217 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-12-23-02-09-44.gh-issue-58956.4OdMdT.rst @@ -0,0 +1 @@ +Fixed a frame reference leak in :mod:`bdb`.
participants (1)
-
gaogaotiantian