Extending The Python Debugger

The Problem

The gdb user defined hooks feature is quite powerful. It let’s you define a “hook” that executes before (or after, if you so wish) either after a command or when execution stops and you drop into the debugger. Check out the docs linked for more detail on that. If you’ve spent any time in a debugger, you’ll know that you inevitably have times when you need to repeat the same sequence of commands again and again, and the hooks feature lets you automate this quite well. I wanted something much smaller — the ability to automatically execute debugger commands every time code execution stops.

The Stuff That Didn’t Quite Work (But Is Cool To Know)

commands

The closest feature that I could find for my use case was the commands command. It allows you to execute a series of commands when a breakpoint of a particular breakpoint number is hit. Certainly useful (consult the official docs for some usage ideas), but clearly falls short of our requirements because a) it wouldn't work with breakpoints defined in the code using a breakpoint() or pdb.set_trace() call because it only works with breakpoint numbers and b) even if it did, it wouldn't execute our commands every time execution stops. It only executes commands when a breakpoint is hit, not when you step over a single line of code using n(ext) for example.

alias

Another technique that one can use to make the debugging process more bearable is the alias feature. It is kinda similar to the alias command of bash and other shells. This lets you define an alias for anything that be legally typed on the pdb prompt. This includes using other aliases you have defined. Here's an example (taken straight from the official pdb docs):

# 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
alias ps pi self

pdbrc

Not many people know that pdb supports a .pdbrc file, which is quite similar to a .bashrc. This file lets you execute any debugger commands you want at the startup of the debugger. It can either be present in the home directory or in the directory from where you fire up the python process (the one in the home directory is executed first if you have .pdbrc files in both places).

display

The display debugger command takes an expression as an argument and displays the value of the exception if it changed each time execution stops in the current frame. I mention this because before learning about this command, I could only think of an implementation of the gdb hooks feature to kinda pull this off, and it is a very common use case.

Building Your Own Pdb

Using Your Pdb With The breakpoint Builtin

As you might already know, we can hardcode a breakpoint into a python program using the following idiom:

import pdb; pdb.set_trace()
import ipdb; ipdb.set_trace()
breakpoint()
❯ PYTHONBREAKPOINT=hookpdb.set_trace python
Python 3.9.5 (default, May 14 2021, 00:00:00)
[GCC 10.3.1 20210422 (Red Hat 10.3.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> breakpoint()
Welcome to HookPdb
--Return--
> /home/ajmal/playground/gevent-hang/hookpdb.py(75)set_trace()->None
-> mypdb.set_trace()
(Pdb)

Concluding Words

As I said earlier, what I have so far is a fairly hacky thing that possibly breaks other features of pdb or has unknown side-effects/consequences. And there is a lot about python, pdb and debuggers that I don’t know, so there might be other solutions to my problem that are easier/better/more robust. Regardless, this little dive into the pdb ecosystem was a fun learning experience for me, and I hope you also found it as fun (and hopefully learned a thing or two as well).

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mohammed Ajmal Siddiqui

Mohammed Ajmal Siddiqui

Full-stack JavaScript developer and coding enthusiast. I love learning new technologies and sharing my knowledge. Find me on ajmalsiddiqui.me