Thursday, February 15, 2007

printf() Debugging

Over the years I've gotten various flack from coworkers on just how much I use printf() debugging when coding. They invariably point me to the awesome debugger in Eclipse, start trying to teach me how to attach to the process or somesuch..

It's not that I don't know HOW to use a debugger, I even will grant you that they are often superior. It's that over the years I've resisted using any tools that lock me into one particular platform. My primary value as a developer is in being able to code. To code in any language, regardless of the tools available to me.

That's why I've only recently moved from emacs as my primary editor (at some point Eclipse just become TOO good to ignore), and why I still use printf debugging as my first shot of figuring out what has gone wrong.

That has served me well. I think there's a certain amount of skill that is built over time as where to put those printf()'s. There's also something to be said for looking at the code first and seeing if it's obvious what is wrong before diving into a debugger. printf debugging is a skill that transcends languages, platforms and operating systems. It's probably safe to say that any platform I'll ever develop on will have some way of outputting something I can see.

I've coded in Perl, PHP, Java, C, C++ and others over the years, and in all cases there have been times where only the most rudimentary debugger was available. When I first started using Java back in the Alpha/Beta days we didn't even have jdb. I don't think PHP even offers a debugger.

A case in point. Today I was setting up some SysV init scripts for feedmonger. Astonishingly it seems everybody out there writes their own init script from scratch, and they all seem rather different. On my search for the 'right way' to do things, I came across start-stop-daemon, a (mostly) Debian utility that takes care of most of the dirty work of starting and stopping things appropriately. (checking if the process is running, sending it stop signals, making pid files etc..) For whatever reason, this excellent tool isn't really available on Redhat systems. Ok, no problem, I grabbed the source (one .h, one .c) and compiled it for our systems. Wrote my init script and doh, it doesn't seem to be working as expected: start-stop-daemon isn't finding the previously running process when duplicate start commands are sent and is trying to start it anyways. No good!

I pondered the docs a bit and really couldn't figure out what was going on. Figuring maybe it was something to do with our 64 bit setup, I decided to add in some.. wait for it.. printf debugging to see if I could figure out what was up.

Turns out my usage was wrong (good old meatsicle bug). If you want start-stop-daemon to check for the process before starting based on the command you cannot use the '--exec' switch, you must instead use the '--startas' switch. This really isn't made terribly clear in the documentation sadly.

Ok, so I'm an idiot sometimes too, but without a bit of printf debugging (on a plain old c executable I wasn't about to gdb) I wouldn't have figured out what was wrong.