In-depth PDB

Nathan Yergler
presentotron.com/nyergler/pdb
github.com/nyergler/in-depth-pdb

Better than print statements!

  • explore state of a running program, or a dead one
  • repeatedly run a program
  • build the tools you need for your program

Explicit Trace Points

Invocation

    import pdb; pdb.set_trace()
  • next: execute current line
  • step: execute current line and stop as soon as possible
  • cont: leave the debugger and let your program continue executing
  • Enter repeats the previous command

Executing Code Under PDB

Running PDB as a Script

    python -m pdb django runserver

pdb.run

    pdb.run("print('Hey')")
    pdb.runcall(int, '4')

Post-Mortem debugging and More Commands

  • Now we have the tools to debug our stuff in interesting ways.
  • Example project: HTTP Service for postfix calculations.
  • When running under pdb (python -m pdb), you get a post mortem debugger after uncaught exceptions

Nice built-ins for inspection

    (Pdb) args    # prints args to current function
    (Pdb) list    # lists 5 lines before and after current point
    (Pdb) ll      # long listing: just the current function/method
    (Pdb) pp var  # pretty-print var

Evaluate expressions with !

    (Pdb) b+c
    Error: ...no +c on path.  whaaaat?  PDB thinks you want to set a breakpoint at "+c"
    (Pdb) !b+c
    [value]
    (Pdb) where # where am I in the call stack? last line is where we are
    (Pdb) up    # move up the stack
    (Pdb) down  # move down the stack

Post-mortem Debugging

  • Effectively acts like a top-level, bare exception handler

      import sys
      def main():
          # stuff
    
      if __name__ == '__main__':
          try:
              sys.exit(main())
          except:
              import pdb; pdb.pm()

Breakpoints

  • Way to look at code without editing it; good for third-party stuff

      (Pdb) break pfcalc.rpn_app  # can break at some callable
      (Pdb) break pfcalc.py:41    # ...or a line number
      (Pdb) break                 # show all breakpoints and how many times they've been triggered
  • Can make breakpoint conditional: only break if python expression is truthy

      (Pdb) break pfcalc.rpn_app, environ['HTTP_METHOD'] != 'GET'

Extending PDB

Aliases

  • Can refer to other aliases
  • Defined where???
      alias dr pp dir(%1)
      alias loc locals().keys()
      alias printdict for key, value in %1.items(): print("{0}: {1}".format(key, value)

Breakpoint Commands

  • Executed when a breakpoint is hit, just like you typed it yourself
  • Anything except next, step, end
      (Pdb) commands 1
      (com) pp self.state
      (com) pp value_or_operator
      (com) continue

.pdbrc Hooray!!!

  • Exists home directory version first, then in current dir
  • Executed line-by-line in pdb
  • Comments allowed, yay!
  • Can setup variable watches!
    • google "How do you watch a variable in pdb" on stackoverflow

See also

  • ipdb
    • syntax highlighting
    • tab completion
  • rdb: PDB over a socket
  • pudb: full screen, console debugger
  • pdb++
  • wdb