[issue7245] better Ctrl-C support in pdb (program can be resumed) (issue216067)

Gregory P. Smith report at bugs.python.org
Sun Feb 28 21:23:31 CET 2010


Gregory P. Smith <greg at krypto.org> added the comment:

Reviewers: gregory.p.smith, Benjamin, ilya.sandler,

Message:
Also, can you take a look at how the pdb unittests work and see if you
can come up with a way to unittest the KeyboardInterrupt behavior?

Particular for the 4 scenarios you outlined in your prior comments in
the bug (those all make sense to me).

http://codereview.appspot.com/216067/diff/2001/2002
File Lib/pdb.py (right):

http://codereview.appspot.com/216067/diff/2001/2002#newcode63
Lib/pdb.py:63: def sigint_handler(self, signum, frame):
Please move this below the __init__ definition.  It makes classes odd to
read when __init__ isn't the first method defined when people are
looking for the constructor to see how to use it.

http://codereview.appspot.com/216067/diff/2001/2002#newcode64
Lib/pdb.py:64: if self.allow_kbdint:
Initialize self.allow_kdbint in __init__ so that a SIGINT coming in
before _cmdloop has run doesn't cause an AttributeError.

http://codereview.appspot.com/216067/diff/2001/2002#newcode215
Lib/pdb.py:215: # keyboard interrupts allow for an easy way to interrupt
"to cancel the current command"

http://codereview.appspot.com/216067/diff/2001/2002#newcode356
Lib/pdb.py:356: #it appears that that when pdb is reading input from a
pipe
Space after the # please.

Also, could you add a comment in here describing what the effect of this
code is?

It looks like you catch KeyboardInterrupt here and remove the particular
interrupted command from the list of commands to run at the current
breakpoint but I may be misreading things as I haven't spent much time
in pdb.py.

Please review this at http://codereview.appspot.com/216067/show

Affected files:
   M     Lib/pdb.py

Index: Lib/pdb.py
===================================================================
--- Lib/pdb.py	(revision 78520)
+++ Lib/pdb.py	(working copy)
@@ -13,8 +13,10 @@
  import re
  import pprint
  import traceback
+import signal

+
  class Restart(Exception):
      """Causes a debugger to be restarted for the debugged python  
program."""
      pass
@@ -58,6 +60,13 @@

  class Pdb(bdb.Bdb, cmd.Cmd):

+    def sigint_handler(self, signum, frame):
+        if self.allow_kbdint:
+            raise KeyboardInterrupt()
+        print >>self.stdout, "\nProgram interrupted. (Use 'cont' to  
resume)."
+        self.set_step()
+        self.set_trace(frame)
+
      def __init__(self, completekey='tab', stdin=None, stdout=None,  
skip=None):
          bdb.Bdb.__init__(self, skip=skip)
          cmd.Cmd.__init__(self, completekey, stdin, stdout)
@@ -72,6 +81,7 @@
              import readline
          except ImportError:
              pass
+        signal.signal(signal.SIGINT, self.sigint_handler)

          # Read $HOME/.pdbrc and ./.pdbrc
          self.rcLines = []
@@ -176,7 +186,7 @@
              if not self.commands_silent[currentbp]:
                  self.print_stack_entry(self.stack[self.curindex])
              if self.commands_doprompt[currentbp]:
-                self.cmdloop()
+                self._cmdloop()
              self.forget()
              return
          return 1
@@ -199,11 +209,22 @@
          self.interaction(frame, exc_traceback)

      # General interaction function
+    def _cmdloop(self):
+        while 1:
+            try:
+                # keyboard interrupts allow for an easy way to interrupt
+                # cancel current command
+                self.allow_kbdint = True
+                self.cmdloop()
+                self.allow_kbdint = False
+                break
+            except KeyboardInterrupt:
+                print >>self.stdout, '--KeyboardInterrupt--'

      def interaction(self, frame, traceback):
          self.setup(frame, traceback)
          self.print_stack_entry(self.stack[self.curindex])
-        self.cmdloop()
+        self._cmdloop()
          self.forget()

      def displayhook(self, obj):
@@ -329,9 +350,18 @@
          prompt_back = self.prompt
          self.prompt = '(com) '
          self.commands_defining = True
-        self.cmdloop()
-        self.commands_defining = False
-        self.prompt = prompt_back
+        try:
+            self.cmdloop()
+        except (KeyboardInterrupt, IOError):
+            #it appears that that when pdb is reading input from a pipe
+            # we may get IOErrors, rather than KeyboardInterrupt
+            self.commands.pop(bnum)   # remove this cmd list
+            self.commands_doprompt.pop(bnum)
+            self.commands_silent.pop(bnum)
+            raise KeyboardInterrupt()
+        finally:
+            self.commands_defining = False
+            self.prompt = prompt_back

      def do_break(self, arg, temporary = 0):
          # break [ ([filename:]lineno | function) [, "condition"] ]

----------
title: better Ctrl-C support in pdb (program can be resumed) -> better Ctrl-C support in pdb (program can be resumed) (issue216067)

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue7245>
_______________________________________


More information about the Python-bugs-list mailing list