Something's Wrong!

Python, debugging, and finding things out the easy way

Download it!

Download this presentation from:

QR Code

As soon as we started programming, we found to our surprise that it wasn't as easy to get programs right as we had thought. Debugging had to be discovered. I can remember the exact instant when I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs.

Maurice Wilkes

Debugging Python code

print statements

For example: def add(arg1, arg2): print "%s, %s" % (arg1, arg2) return arg1 + arg2 Barrier to entry is tiny: Usually less than 15 characters.
Useful for visualizing program flow and seeing how things play out sequentially: a = [0, 1, 2] for i in len(a) + 1: print a[i]
Output: 0 1 2 Traceback (most recent call last): File "", line 2, in IndexError: list index out of range


The logging module in the standard library is very featureful in recent versions of Python. + Format strings with useful arguments (time, line number, etc.) + Circular logging + Verbosity levels + Multiple loggers
All it takes to use logging: import logging logger = logging.getLogger("main") logger.setLevel(logging.DEBUG) handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) formatter = logging.Formatter("%(levelname)s %(asctime)s " + "%(funcName)s:%(lineno)d %(message)s") handler.setFormatter(formatter) logger.addHandler(handler) def main(): logger.debug("Some useful information") if __name__ == "__main__": main()

plac: command line arguments

Adding a debugging flag to ``: import plac @plac.annotations( debug=("Display debug output", "flag")) def main(debug=False): if debug: print "Some useful information" if __name__ == "__main__":
Output: $ ./ -h usage: [-h] [-d] optional arguments: -h, --help show this help message and exit -d, --debug Display debug output


An improved REPL with colors, tab-completion, etc. This line will kick you into ipython for any uncaught exception your program encounters: from IPython.Shell import IPShellEmbed ipshell = IPShellEmbed() ipshell() # this call anywhere in your program will start IPython You can achieve the same effect by running your .py file with ipython: $ ipython

Exploring with ipython

Let's say we're playing with a new API: flickr.authenticate() picture = flickr.get_a_picture_object('unique-identifier') ipshell() # drop into an ipython shell At this point you can manually invoke an ipython shell to interactively play with that variable using tab-completion: In [1]: picture.<TAB> picture.description picture.location picture.tags picture.title

The ? operator

An easy way to get a high-level description of an object: In [1]: a = [1, 2, 3] In [1]: a? Type: list Base Class: String Form: [1, 2, 3] Namespace: Interactive Length: 3 Docstring: list() -> new empty list list(iterable) -> new list initialized from iterable's items

Debugging things with Python

Debugging with WinAppDbg: def action_callback(event): stack = event.get_thread().get_sp() address = event.get_process().read_pointer(stack) pid = event.get_pid() tid = event.get_tid() message = "kernel32!CreateFileW called from %s by thread %d " + "at process %d" print message % (HexDump.address(address), tid, pid) class MyEventHandler(EventHandler): def load_dll(self, event): module = event.get_module() if module.match_name("kernel32.dll"): pid = event.get_pid() address = module.resolve("CreateFileW") event.debug.break_at(pid, address, action_callback)




The Web




Windows Internals

Linux Internals


SystemTap provides free software (GPL) infrastructure to simplify the gathering of information about the running Linux system.

"Gathering of information?"



Better tools!

Think like a debugger