6666# NOTE: the actual command documentation is collected from docstrings of the
6767# commands and is appended to __doc__ after the class has been defined.
6868
69+ import os
70+ import re
6971import sys
7072import cmd
7173import bdb
7274import dis
73- import os
74- import re
7575import code
7676import pprint
77+ import signal
7778import inspect
7879import traceback
7980import linecache
@@ -133,7 +134,8 @@ def lasti2lineno(code, lasti):
133134
134135class Pdb (bdb .Bdb , cmd .Cmd ):
135136
136- def __init__ (self , completekey = 'tab' , stdin = None , stdout = None , skip = None ):
137+ def __init__ (self , completekey = 'tab' , stdin = None , stdout = None , skip = None ,
138+ nosigint = False ):
137139 bdb .Bdb .__init__ (self , skip = skip )
138140 cmd .Cmd .__init__ (self , completekey , stdin , stdout )
139141 if stdout :
@@ -148,6 +150,8 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None):
148150 import readline
149151 except ImportError :
150152 pass
153+ self .allow_kbdint = False
154+ self .nosigint = nosigint
151155
152156 # Read $HOME/.pdbrc and ./.pdbrc
153157 self .rcLines = []
@@ -174,6 +178,15 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None):
174178 self .commands_bnum = None # The breakpoint number for which we are
175179 # defining a list
176180
181+ def sigint_handler (self , signum , frame ):
182+ if self .allow_kbdint :
183+ raise KeyboardInterrupt
184+ self .message ("\n Program interrupted. (Use 'cont' to resume)." )
185+ self .set_step ()
186+ self .set_trace (frame )
187+ # restore previous signal handler
188+ signal .signal (signal .SIGINT , self ._previous_sigint_handler )
189+
177190 def reset (self ):
178191 bdb .Bdb .reset (self )
179192 self .forget ()
@@ -261,7 +274,7 @@ def bp_commands(self, frame):
261274 if not self .commands_silent [currentbp ]:
262275 self .print_stack_entry (self .stack [self .curindex ])
263276 if self .commands_doprompt [currentbp ]:
264- self .cmdloop ()
277+ self ._cmdloop ()
265278 self .forget ()
266279 return
267280 return 1
@@ -286,6 +299,17 @@ def user_exception(self, frame, exc_info):
286299 self .interaction (frame , exc_traceback )
287300
288301 # General interaction function
302+ def _cmdloop (self ):
303+ while True :
304+ try :
305+ # keyboard interrupts allow for an easy way to cancel
306+ # the current command, so allow them during interactive input
307+ self .allow_kbdint = True
308+ self .cmdloop ()
309+ self .allow_kbdint = False
310+ break
311+ except KeyboardInterrupt :
312+ self .message ('--KeyboardInterrupt--' )
289313
290314 def interaction (self , frame , traceback ):
291315 if self .setup (frame , traceback ):
@@ -294,7 +318,7 @@ def interaction(self, frame, traceback):
294318 self .forget ()
295319 return
296320 self .print_stack_entry (self .stack [self .curindex ])
297- self .cmdloop ()
321+ self ._cmdloop ()
298322 self .forget ()
299323
300324 def displayhook (self , obj ):
@@ -909,6 +933,9 @@ def do_continue(self, arg):
909933 """c(ont(inue))
910934 Continue execution, only stop when a breakpoint is encountered.
911935 """
936+ if not self .nosigint :
937+ self ._previous_sigint_handler = \
938+ signal .signal (signal .SIGINT , self .sigint_handler )
912939 self .set_continue ()
913940 return 1
914941 do_c = do_cont = do_continue
0 commit comments