https://github.com/python/cpython/commit/dc77f1914d614bab04769616d7bc6674ee723f47
commit: dc77f1914d614bab04769616d7bc6674ee723f47
branch: 3.13
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: gaogaotiantian <gaogaotiant...@hotmail.com>
date: 2025-01-17T12:49:15-05:00
summary:

[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 <gaogaotiant...@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 ece0a29fe9f3b1..3a4453d95f6596 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -382,6 +382,7 @@ def set_trace(self, frame=None):
             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 @@ def set_continue(self):
             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 9b6dffda1cfcd1..cb0a3405c58e55 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -383,6 +383,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 5b25f514b9e772..c34046f0e5bb6f 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()
+    > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(4)frame_leaker()
+    -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+    (Pdb) continue
+    1
+    > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(4)frame_leaker()
+    -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+    (Pdb) next
+    > <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]>(4)frame_leaker()
+    -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
+    (Pdb) return
+    --Return--
+    > <doctest test.test_pdb.test_pdb_frame_refleak[0]>(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 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`.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to