Skip to content

Commit f45da82

Browse files
[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 767c89b) Co-authored-by: Tian Gao <gaogaotiantian@hotmail.com>
1 parent dfd75df commit f45da82

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

Lib/bdb.py

+2
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ def set_trace(self, frame=None):
340340
self.botframe = frame
341341
frame = frame.f_back
342342
self.set_step()
343+
self.enterframe = None
343344
sys.settrace(self.trace_dispatch)
344345

345346
def set_continue(self):
@@ -356,6 +357,7 @@ def set_continue(self):
356357
while frame and frame is not self.botframe:
357358
del frame.f_trace
358359
frame = frame.f_back
360+
self.enterframe = None
359361

360362
def set_quit(self):
361363
"""Set quitting attribute to True.

Lib/pdb.py

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ def forget(self):
281281
if hasattr(self, 'curframe') and self.curframe:
282282
self.curframe.f_globals.pop('__pdb_convenience_variables', None)
283283
self.curframe = None
284+
self.curframe_locals = {}
284285
self.tb_lineno.clear()
285286

286287
def setup(self, f, tb):

Lib/test/test_pdb.py

+52
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,58 @@ def test_pdb_ambiguous_statements():
19811981
(Pdb) continue
19821982
"""
19831983

1984+
def test_pdb_frame_refleak():
1985+
"""
1986+
pdb should not leak reference to frames
1987+
1988+
>>> def frame_leaker(container):
1989+
... import sys
1990+
... container.append(sys._getframe())
1991+
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
1992+
... pass
1993+
1994+
>>> def test_function():
1995+
... import gc
1996+
... container = []
1997+
... frame_leaker(container) # c
1998+
... print(len(gc.get_referrers(container[0])))
1999+
... container = []
2000+
... frame_leaker(container) # n c
2001+
... print(len(gc.get_referrers(container[0])))
2002+
... container = []
2003+
... frame_leaker(container) # r c
2004+
... print(len(gc.get_referrers(container[0])))
2005+
2006+
>>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
2007+
... 'continue',
2008+
... 'next',
2009+
... 'continue',
2010+
... 'return',
2011+
... 'continue',
2012+
... ]):
2013+
... test_function()
2014+
> <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()
2015+
-> pass
2016+
(Pdb) continue
2017+
1
2018+
> <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()
2019+
-> pass
2020+
(Pdb) next
2021+
--Return--
2022+
> <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()->None
2023+
-> pass
2024+
(Pdb) continue
2025+
1
2026+
> <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()
2027+
-> pass
2028+
(Pdb) return
2029+
--Return--
2030+
> <doctest test.test_pdb.test_pdb_frame_refleak[0]>(5)frame_leaker()->None
2031+
-> pass
2032+
(Pdb) continue
2033+
1
2034+
"""
2035+
19842036
def test_pdb_issue_gh_65052():
19852037
"""See GH-65052
19862038
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a frame reference leak in :mod:`bdb`.

0 commit comments

Comments
 (0)