Issue #20766: Fix references leaked by pdb in the handling of SIGINT handlers.

This commit is contained in:
Xavier de Gaye 2016-10-12 20:13:24 +02:00
parent fd28cbef4b
commit 10e54aeaa2
3 changed files with 33 additions and 3 deletions

View File

@ -134,6 +134,8 @@ line_prefix = '\n-> ' # Probably a better default
class Pdb(bdb.Bdb, cmd.Cmd): class Pdb(bdb.Bdb, cmd.Cmd):
_previous_sigint_handler = None
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
nosigint=False): nosigint=False):
bdb.Bdb.__init__(self, skip=skip) bdb.Bdb.__init__(self, skip=skip)
@ -187,8 +189,6 @@ class Pdb(bdb.Bdb, cmd.Cmd):
self.message("\nProgram interrupted. (Use 'cont' to resume).") self.message("\nProgram interrupted. (Use 'cont' to resume).")
self.set_step() self.set_step()
self.set_trace(frame) self.set_trace(frame)
# restore previous signal handler
signal.signal(signal.SIGINT, self._previous_sigint_handler)
def reset(self): def reset(self):
bdb.Bdb.reset(self) bdb.Bdb.reset(self)
@ -337,6 +337,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
(expr, newvalue, oldvalue)) (expr, newvalue, oldvalue))
def interaction(self, frame, traceback): def interaction(self, frame, traceback):
# Restore the previous signal handler at the Pdb prompt.
if Pdb._previous_sigint_handler:
signal.signal(signal.SIGINT, Pdb._previous_sigint_handler)
Pdb._previous_sigint_handler = None
if self.setup(frame, traceback): if self.setup(frame, traceback):
# no interaction desired at this time (happens if .pdbrc contains # no interaction desired at this time (happens if .pdbrc contains
# a command like "continue") # a command like "continue")
@ -1037,7 +1041,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
""" """
if not self.nosigint: if not self.nosigint:
try: try:
self._previous_sigint_handler = \ Pdb._previous_sigint_handler = \
signal.signal(signal.SIGINT, self.sigint_handler) signal.signal(signal.SIGINT, self.sigint_handler)
except ValueError: except ValueError:
# ValueError happens when do_continue() is invoked from # ValueError happens when do_continue() is invoked from

View File

@ -911,6 +911,29 @@ def test_pdb_next_command_subiterator():
(Pdb) continue (Pdb) continue
""" """
def test_pdb_issue_20766():
"""Test for reference leaks when the SIGINT handler is set.
>>> def test_function():
... i = 1
... while i <= 2:
... sess = pdb.Pdb()
... sess.set_trace(sys._getframe())
... print('pdb %d: %s' % (i, sess._previous_sigint_handler))
... i += 1
>>> with PdbTestInput(['continue',
... 'continue']):
... test_function()
> <doctest test.test_pdb.test_pdb_issue_20766[0]>(6)test_function()
-> print('pdb %d: %s' % (i, sess._previous_sigint_handler))
(Pdb) continue
pdb 1: <built-in function default_int_handler>
> <doctest test.test_pdb.test_pdb_issue_20766[0]>(5)test_function()
-> sess.set_trace(sys._getframe())
(Pdb) continue
pdb 2: <built-in function default_int_handler>
"""
class PdbTestCase(unittest.TestCase): class PdbTestCase(unittest.TestCase):

View File

@ -107,6 +107,9 @@ Core and Builtins
Library Library
------- -------
- Issue #20766: Fix references leaked by pdb in the handling of SIGINT
handlers.
- Issue #26293: Fixed writing ZIP files that starts not from the start of the - Issue #26293: Fixed writing ZIP files that starts not from the start of the
file. Offsets in ZIP file now are relative to the start of the archive in file. Offsets in ZIP file now are relative to the start of the archive in
conforming to the specification. conforming to the specification.