I'm a dynamically typed language fan boy. I've dabbled in all sorts of languages, but got my first development job working with PHP and Javascript, graduated to Python, and then did the C/C++ and Java stints as well. One thing I'm quite used to doing is writing print statements for debugging. In large C/C++ or Java environments, I found this quite impractical, and eventually became quite intimate with debugging tools in those languages. Until recently, however, I continued using print statements for working with scripted languages like Python. Now I use pdb for almost every problem I encounter in python.
A while ago, I battled a nasty Entertainer bug. It was repeatable, but not consistently. I would start the backend, and the it would start indexing videos from the configured video folders. Then, for no reason, the backend would die. I was able to trace the problem back to the VideoThumbnailer, which would be my baby. Crap. So I started adding print statements, so that I could see if the thumbnailer was consistently dying on the same video (thinking it might have been a codec problem with GStreamer). What I found was that the backend rarely died in the same spot, and since the thumbnailer didn't create thumbnails for videos that already had thumbnails, once it got past a video it had failed on before, it never struggled on it again. However, with the multi-threaded environment of entertainer, it was quite difficult to debug.
Eventually, I followed the yellow brick road to see the Google. I typed in 'python debugger' and found the first page of results full of pdb articles. "Oh no," I thought, "anything but the confusing and difficult pdb!" Alas, once I forced myself to work with it, I found that it was very simple to use (and that the pydev eclipse plugin makes it so much more complicated than it needs to be). I'm still only using a small subset of the things that pdb can do, but frankly, I can't see a need for anything more than what I used it for (setting a breakpoint, reading local variables, seeing a backtrace, and stepping through code).
First, I decided where I wanted to have pdb stop and give me a debugging console (setting the breakpoint). When that was decided, I added the following code:
import pdbpdb.set_trace()That's it! Now run the code, and you'll find that instead of complete execution, you'll be at the (Pdb) prompt. Above your prompt, you should see the pdb.set_trace() call that created the console. I'm not one of those people who fears a command prompt, so if you are, I apologize. However, this isn't nearly as complicated as a shell prompt. You've got only a few keys to worry about:
- n (next) - Hitting 'n' at this prompt will execute the current line of code and go to the next line.
- c (continue) - If you've gotten to the point where you know your bug is fixed, and you want to just close the debugger, hit 'c' to just continue executing the program. This will complete execution, provided that you have no more calls to pdb.set_trace()
- s (step into) - If you're at a function or method call on the prompt, and you'd like to see what's going on inside that function, stepping into it will allow you to follow execution into the function. If you don't want to see what's going on in the function, 'n' is your character.
- l (list) - Wait. Where was I in the code again? Yea, I guarantee that'll happen to you. Hitting 'l' will give you a chunk of code in the area you are, with a nice little -> where you are currently.
- bt (backtrace) - Okay, so now I know where I am, but how did I get here? 'bt' gives you a backtrace, showing you the start of execution, and all the function and method calls that got you where you are today.
- p
(print) - Okay, so what's the value of variable foo? 'p foo' will print it's value, allowing you see how the variable is changing as you walk through the code. - q (quit) - Ah! Found the bug. Let's quit this session and fix it!
- enter (repeat last command) - Tired of hitting 'n' over and over? How 'bout just using 'n' once, and then hitting 'Enter' over and over. It's a bigger key, and less likely to get fat fingered. I don't use it, but it's there if you want it.
Needless to say, debuggers are the tools that would make your life easier if you just learned how to use them. Since my experience with the debugger, I've chatted with a few pythonistas and developers from other languages, and to my surprise have received varying responses. I would say that if you've spent more than 5 minutes writing print statements and running your code, do yourself a favor and fire up the debugger. There might be a learning curve now, but you'll be a better developer for it.


Comments for HOWTO : Python Debugging with pdb