#7245: Add a SIGINT handler on continue in pdb that allows to break a program again by pressing Ctrl-C.
This commit is contained in:
parent
1ed77f300b
commit
44f2b640ff
|
@ -135,7 +135,8 @@ The ``run_*`` functions and :func:`set_trace` are aliases for instantiating the
|
||||||
:class:`Pdb` class and calling the method of the same name. If you want to
|
:class:`Pdb` class and calling the method of the same name. If you want to
|
||||||
access further features, you have to do this yourself:
|
access further features, you have to do this yourself:
|
||||||
|
|
||||||
.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None)
|
.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \
|
||||||
|
nosigint=False)
|
||||||
|
|
||||||
:class:`Pdb` is the debugger class.
|
:class:`Pdb` is the debugger class.
|
||||||
|
|
||||||
|
@ -146,6 +147,11 @@ access further features, you have to do this yourself:
|
||||||
patterns. The debugger will not step into frames that originate in a module
|
patterns. The debugger will not step into frames that originate in a module
|
||||||
that matches one of these patterns. [1]_
|
that matches one of these patterns. [1]_
|
||||||
|
|
||||||
|
By default, Pdb sets a handler for the SIGINT signal (which is sent when the
|
||||||
|
user presses Ctrl-C on the console) when you give a ``continue`` command.
|
||||||
|
This allows you to break into the debugger again by pressing Ctrl-C. If you
|
||||||
|
want Pdb not to touch the SIGINT handler, set *nosigint* tot true.
|
||||||
|
|
||||||
Example call to enable tracing with *skip*::
|
Example call to enable tracing with *skip*::
|
||||||
|
|
||||||
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
|
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
|
||||||
|
@ -153,6 +159,10 @@ access further features, you have to do this yourself:
|
||||||
.. versionadded:: 3.1
|
.. versionadded:: 3.1
|
||||||
The *skip* argument.
|
The *skip* argument.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
The *nosigint* argument. Previously, a SIGINT handler was never set by
|
||||||
|
Pdb.
|
||||||
|
|
||||||
.. method:: run(statement, globals=None, locals=None)
|
.. method:: run(statement, globals=None, locals=None)
|
||||||
runeval(expression, globals=None, locals=None)
|
runeval(expression, globals=None, locals=None)
|
||||||
runcall(function, *args, **kwds)
|
runcall(function, *args, **kwds)
|
||||||
|
|
|
@ -214,7 +214,7 @@ class Bdb:
|
||||||
def set_continue(self):
|
def set_continue(self):
|
||||||
# Don't stop except at breakpoints or when finished
|
# Don't stop except at breakpoints or when finished
|
||||||
self._set_stopinfo(self.botframe, None, -1)
|
self._set_stopinfo(self.botframe, None, -1)
|
||||||
if not self.breaks:
|
if not self.breaks and not self.watching:
|
||||||
# no breakpoints; run without debugger overhead
|
# no breakpoints; run without debugger overhead
|
||||||
sys.settrace(None)
|
sys.settrace(None)
|
||||||
frame = sys._getframe().f_back
|
frame = sys._getframe().f_back
|
||||||
|
|
37
Lib/pdb.py
37
Lib/pdb.py
|
@ -66,14 +66,15 @@ Debugger commands
|
||||||
# NOTE: the actual command documentation is collected from docstrings of the
|
# NOTE: the actual command documentation is collected from docstrings of the
|
||||||
# commands and is appended to __doc__ after the class has been defined.
|
# commands and is appended to __doc__ after the class has been defined.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import cmd
|
import cmd
|
||||||
import bdb
|
import bdb
|
||||||
import dis
|
import dis
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import code
|
import code
|
||||||
import pprint
|
import pprint
|
||||||
|
import signal
|
||||||
import inspect
|
import inspect
|
||||||
import traceback
|
import traceback
|
||||||
import linecache
|
import linecache
|
||||||
|
@ -133,7 +134,8 @@ line_prefix = '\n-> ' # Probably a better default
|
||||||
|
|
||||||
class Pdb(bdb.Bdb, cmd.Cmd):
|
class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
|
|
||||||
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None):
|
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
|
||||||
|
nosigint=False):
|
||||||
bdb.Bdb.__init__(self, skip=skip)
|
bdb.Bdb.__init__(self, skip=skip)
|
||||||
cmd.Cmd.__init__(self, completekey, stdin, stdout)
|
cmd.Cmd.__init__(self, completekey, stdin, stdout)
|
||||||
if stdout:
|
if stdout:
|
||||||
|
@ -148,6 +150,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
import readline
|
import readline
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
self.allow_kbdint = False
|
||||||
|
self.nosigint = nosigint
|
||||||
|
|
||||||
# Read $HOME/.pdbrc and ./.pdbrc
|
# Read $HOME/.pdbrc and ./.pdbrc
|
||||||
self.rcLines = []
|
self.rcLines = []
|
||||||
|
@ -174,6 +178,15 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self.commands_bnum = None # The breakpoint number for which we are
|
self.commands_bnum = None # The breakpoint number for which we are
|
||||||
# defining a list
|
# defining a list
|
||||||
|
|
||||||
|
def sigint_handler(self, signum, frame):
|
||||||
|
if self.allow_kbdint:
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
self.message("\nProgram interrupted. (Use 'cont' to resume).")
|
||||||
|
self.set_step()
|
||||||
|
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)
|
||||||
self.forget()
|
self.forget()
|
||||||
|
@ -261,7 +274,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
if not self.commands_silent[currentbp]:
|
if not self.commands_silent[currentbp]:
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
self.print_stack_entry(self.stack[self.curindex])
|
||||||
if self.commands_doprompt[currentbp]:
|
if self.commands_doprompt[currentbp]:
|
||||||
self.cmdloop()
|
self._cmdloop()
|
||||||
self.forget()
|
self.forget()
|
||||||
return
|
return
|
||||||
return 1
|
return 1
|
||||||
|
@ -286,6 +299,17 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self.interaction(frame, exc_traceback)
|
self.interaction(frame, exc_traceback)
|
||||||
|
|
||||||
# General interaction function
|
# General interaction function
|
||||||
|
def _cmdloop(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# keyboard interrupts allow for an easy way to cancel
|
||||||
|
# the current command, so allow them during interactive input
|
||||||
|
self.allow_kbdint = True
|
||||||
|
self.cmdloop()
|
||||||
|
self.allow_kbdint = False
|
||||||
|
break
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
self.message('--KeyboardInterrupt--')
|
||||||
|
|
||||||
def interaction(self, frame, traceback):
|
def interaction(self, frame, traceback):
|
||||||
if self.setup(frame, traceback):
|
if self.setup(frame, traceback):
|
||||||
|
@ -294,7 +318,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
self.forget()
|
self.forget()
|
||||||
return
|
return
|
||||||
self.print_stack_entry(self.stack[self.curindex])
|
self.print_stack_entry(self.stack[self.curindex])
|
||||||
self.cmdloop()
|
self._cmdloop()
|
||||||
self.forget()
|
self.forget()
|
||||||
|
|
||||||
def displayhook(self, obj):
|
def displayhook(self, obj):
|
||||||
|
@ -909,6 +933,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
"""c(ont(inue))
|
"""c(ont(inue))
|
||||||
Continue execution, only stop when a breakpoint is encountered.
|
Continue execution, only stop when a breakpoint is encountered.
|
||||||
"""
|
"""
|
||||||
|
if not self.nosigint:
|
||||||
|
self._previous_sigint_handler = \
|
||||||
|
signal.signal(signal.SIGINT, self.sigint_handler)
|
||||||
self.set_continue()
|
self.set_continue()
|
||||||
return 1
|
return 1
|
||||||
do_c = do_cont = do_continue
|
do_c = do_cont = do_continue
|
||||||
|
|
|
@ -49,6 +49,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #7245: Add a SIGINT handler in pdb that allows to break a program
|
||||||
|
again after a "continue" command.
|
||||||
|
|
||||||
- Add the "interact" pdb command.
|
- Add the "interact" pdb command.
|
||||||
|
|
||||||
- Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf.
|
- Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf.
|
||||||
|
|
Loading…
Reference in New Issue