summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-07-30 08:29:39 (GMT)
committerGeorg Brandl <georg@python.org>2010-07-30 08:29:39 (GMT)
commite023091815e4946e42c1af102be1f258b2f47cb8 (patch)
treefe5b2c9d398005733710fea747f6658cd21907cf
parent1e30bd3753e7b08dce13ff1e18ac1ae5c397fcea (diff)
downloadcpython-e023091815e4946e42c1af102be1f258b2f47cb8.zip
cpython-e023091815e4946e42c1af102be1f258b2f47cb8.tar.gz
cpython-e023091815e4946e42c1af102be1f258b2f47cb8.tar.bz2
#1437051: allow "continue"/"next"/etc. in .pdbrc, also add pdb -c option to give these commands. This allows to run a script until an exception occurs.
-rw-r--r--Doc/library/pdb.rst17
-rwxr-xr-xLib/pdb.py73
-rw-r--r--Misc/NEWS4
3 files changed, 72 insertions, 22 deletions
diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst
index 654af8e..e279db8 100644
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -44,11 +44,15 @@ example::
python3 -m pdb myscript.py
When invoked as a script, pdb will automatically enter post-mortem debugging if
-the program being debugged exits abnormally. After post-mortem debugging (or
-after normal exit of the program), pdb will restart the program. Automatic
+the program being debugged exits abnormally. After post-mortem debugging (or
+after normal exit of the program), pdb will restart the program. Automatic
restarting preserves pdb's state (such as breakpoints) and in most cases is more
useful than quitting the debugger upon program's exit.
+.. versionadded:: 3.2
+ :file:`pdb.py` now accepts a ``-c`` option that executes commands as if given
+ in a :file:`.pdbrc` file, see :ref:`debugger-commands`.
+
The typical usage to break into the debugger from a running program is to
insert ::
@@ -202,6 +206,11 @@ prompt. This is particularly useful for aliases. If both files exist, the one
in the home directory is read first and aliases defined there can be overridden
by the local file.
+.. versionchanged:: 3.2
+ :file:`.pdbrc` can now contain commands that continue debugging, such as
+ :pdbcmd:`continue` or :pdbcmd:`next`. Previously, these commands had no
+ effect.
+
.. pdbcommand:: h(elp) [command]
@@ -388,9 +397,9 @@ by the local file.
As an example, here are two useful aliases (especially when placed in the
:file:`.pdbrc` file)::
- #Print instance variables (usage "pi classInst")
+ # Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
- #Print instance variables in self
+ # Print instance variables in self
alias ps pi self
.. pdbcommand:: unalias name
diff --git a/Lib/pdb.py b/Lib/pdb.py
index b775a12..c16cde6 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -332,19 +332,26 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# locals whenever the .f_locals accessor is called, so we
# cache it here to ensure that modifications are not overwritten.
self.curframe_locals = self.curframe.f_locals
- self.execRcLines()
+ return self.execRcLines()
# Can be executed earlier than 'setup' if desired
def execRcLines(self):
- if self.rcLines:
- # Make local copy because of recursion
- rcLines = self.rcLines
- # executed only once
- self.rcLines = []
- for line in rcLines:
- line = line[:-1]
- if len(line) > 0 and line[0] != '#':
- self.onecmd(line)
+ if not self.rcLines:
+ return
+ # local copy because of recursion
+ rcLines = self.rcLines
+ rcLines.reverse()
+ # execute every line only once
+ self.rcLines = []
+ while rcLines:
+ line = rcLines.pop().strip()
+ if line and line[0] != '#':
+ if self.onecmd(line):
+ # if onecmd returns True, the command wants to exit
+ # from the interaction, save leftover rc lines
+ # to execute before next interaction
+ self.rcLines += reversed(rcLines)
+ return True
# Override Bdb methods
@@ -367,7 +374,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
if self.bp_commands(frame):
self.interaction(frame, None)
- def bp_commands(self,frame):
+ def bp_commands(self, frame):
"""Call every command that was set for the current active breakpoint
(if there is one).
@@ -409,7 +416,11 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# General interaction function
def interaction(self, frame, traceback):
- self.setup(frame, traceback)
+ if self.setup(frame, traceback):
+ # no interaction desired at this time (happens if .pdbrc contains
+ # a command like "continue")
+ self.forget()
+ return
self.print_stack_entry(self.stack[self.curindex])
self.cmdloop()
self.forget()
@@ -1497,17 +1508,42 @@ def help():
import pydoc
pydoc.pager(__doc__)
+_usage = """\
+usage: pdb.py [-c command] ... pyfile [arg] ...
+
+Debug the Python program given by pyfile.
+
+Initial commands are read from .pdbrc files in your home directory
+and in the current directory, if they exist. Commands supplied with
+-c are executed after commands from .pdbrc files.
+
+To let the script run until an exception occurs, use "-c continue".
+To let the script run until a given line X in the debugged file, use
+"-c 'break X' -c continue"."""
+
def main():
- if not sys.argv[1:] or sys.argv[1] in ("--help", "-h"):
- print("usage: pdb.py scriptfile [arg] ...")
+ import getopt
+
+ opts, args = getopt.getopt(sys.argv[1:], 'hc:', ['--help', '--command='])
+
+ if not args:
+ print(_usage)
sys.exit(2)
- mainpyfile = sys.argv[1] # Get script filename
+ commands = []
+ for opt, optarg in opts:
+ if opt in ['-h', '--help']:
+ print(_usage)
+ sys.exit()
+ elif opt in ['-c', '--command']:
+ commands.append(optarg)
+
+ mainpyfile = args[0] # Get script filename
if not os.path.exists(mainpyfile):
print('Error:', mainpyfile, 'does not exist')
sys.exit(1)
- del sys.argv[0] # Hide "pdb.py" from argument list
+ sys.argv[:] = args # Hide "pdb.py" and pdb options from argument list
# Replace pdb's dir with script's dir in front of module search path.
sys.path[0] = os.path.dirname(mainpyfile)
@@ -1517,6 +1553,7 @@ def main():
# changed by the user from the command line. There is a "restart" command
# which allows explicit specification of command line arguments.
pdb = Pdb()
+ pdb.rcLines.extend(commands)
while True:
try:
pdb._runscript(mainpyfile)
@@ -1525,10 +1562,10 @@ def main():
print("The program finished and will be restarted")
except Restart:
print("Restarting", mainpyfile, "with arguments:")
- print("\t" + " ".join(sys.argv[1:]))
+ print("\t" + " ".join(args))
except SystemExit:
# In most cases SystemExit does not warrant a post-mortem session.
- print("The program exited via sys.exit(). Exit status: ", end=' ')
+ print("The program exited via sys.exit(). Exit status:", end=' ')
print(sys.exc_info()[1])
except:
traceback.print_exc()
diff --git a/Misc/NEWS b/Misc/NEWS
index b8d3a36..c72107a 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -475,6 +475,10 @@ C-API
Library
-------
+- Issue #1437051: For pdb, allow "continue" and related commands in
+ .pdbrc files. Also, add a command-line option "-c" that runs a
+ command as if given in .pdbrc.
+
- Issue #4179: In pdb, allow "list ." as a command to return to the
currently debugged line.