From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 17 Jan 2025 17:49:15 +0000 (+0100) Subject: [3.13] gh-58956: Fix a frame refleak in bdb (GH-128190) (#128947) X-Git-Tag: v3.13.2~95 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dc77f1914d614bab04769616d7bc6674ee723f47;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-58956: Fix a frame refleak in bdb (GH-128190) (#128947) * gh-58956: Fix a frame refleak in bdb (GH-128190) (cherry picked from commit 767c89ba7c5a70626df6e75eb56b546bf911b997) Co-authored-by: Tian Gao --- diff --git a/Lib/bdb.py b/Lib/bdb.py index ece0a29fe9f3..3a4453d95f65 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -382,6 +382,7 @@ class Bdb: frame.f_trace_lines = True frame = frame.f_back self.set_stepinstr() + self.enterframe = None sys.settrace(self.trace_dispatch) def set_continue(self): @@ -401,6 +402,7 @@ class Bdb: for frame, (trace_lines, trace_opcodes) in self.frame_trace_lines_opcodes.items(): frame.f_trace_lines, frame.f_trace_opcodes = trace_lines, trace_opcodes self.frame_trace_lines_opcodes = {} + self.enterframe = None def set_quit(self): """Set quitting attribute to True. diff --git a/Lib/pdb.py b/Lib/pdb.py index 9b6dffda1cfc..cb0a3405c58e 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -383,6 +383,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): 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 5b25f514b9e7..c34046f0e5bb 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -2810,6 +2810,57 @@ def test_pdb_f_trace_lines(): (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() + > (4)frame_leaker() + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) continue + 1 + > (4)frame_leaker() + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) next + > (5)frame_leaker() + -> pass + (Pdb) continue + 1 + > (4)frame_leaker() + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) return + --Return-- + > (5)frame_leaker()->None + -> pass + (Pdb) continue + 1 + """ + def test_pdb_function_break(): """Testing the line number of break on function 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 000000000000..b78bc5aaf442 --- /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`.