HACKER Q&A
📣 jnxx

When it is better to use printf vs. a debugger?


I have right now one burning question around development practices:

There seem to be two traditions in the field of debugging. One is to use things like printf or kprintf, to print the current state of a program.

The other is to use some of the many debuggers that are around, and inspect the state of the running program, along the call stack.

I think this is, to some degree, probably often a kind of personality-related preference. Personally, I like to use printf, because it matches well with what I call "the scientific method of debugging":

1. I have an idea what a program should do

2. I observe something that is different - that is, my mental model of what the program does diverges at some point from reality

3. I try to make a more refined mental model of what might be happening

4. I test that mental model by inserting print commands at very specific points in the code

5. I observe what happens. based on that, I possibly modify the code, and go back to number 2.

For me, this has turned out to work surprisingly well in a number of domain, such as concurrent real-time systems, complex signal processing, and more. (The nice thing abpout printf in concurrent systems is that it serializes events, which helps).

Other people, I see, prefer to use a debugger. My hypothesis is now that this is due to a combination of both personality as well as concrete tasks where a debugger might be suited better.

So, what I am interested in is your observations of specific cases and circumstances when one methodology might work better than the other. Or maybe it also matters how to do each, to have good results.

What is your experience?


  👤 db48x Accepted Answer ✓
A third alternative is to use a better debugger. I recommend Pernosco (https://pernos.co/). Pernsoco lets you record your program once, and then builds a database out of the recording. You can quickly get a list of all the times your program hit a certain line, and you can then print local variables from each of those execution points. To make this more concrete, you can click on line number 442 to see a list of all the times your program was at line number 442. If you then type the expression "foo" into the query window, the list will update to show the value of the variable foo at every one of those occurrences. There's no need to edit the printfs, recompile, and rerun the program.

👤 paulriddle
I think for the vast majority of cases it is better to use whatever you're most comfortable with. Some people just don't have the endurance to learn gdb or lldb, or they are allergic to Visual Studio on Windows because of how big and slow it is. They just use print statements instead. Some people have learned a few workflows with a debugger of their choice and for them it is easy to fire up a debugger.

However, for some things like debugging Windows kernel trickery it is impossible to use print statements.

Personally I like debuggers.