Live data from Hacker News

The unreasonable effectiveness of print debugging

buttondown.email

191–200 of 366 posts

Re: The unreasonable effectiveness of print debugging

#191
post #37

Earlier quoted context omitted.

OK. And I've also cringed watching ninjas step through code slowly, reading everything, spending 20 mins catching something 2 print statements would have achieved. Debuggers aren't bad. But neither is printing. Knowing when to reach for them is probably a bit more key.

> And I've also cringed watching ninjas step through code slowly, reading everything, spending 20 mins catching something 2 print statements would have achieved. The problem is that the two print statements will only catch the bug if they are the right two, based on a correct hypothesis of what the bug is. Which, with a debugger, won’t require stepping, but setting two breakpoints, doing a run-to-breakpoint, and insp…

But with print statements if the first place I put them doesn't work, I can start doing bisects and quickly find the right place to print.

As you note, debugger breakpoints aren't magically better than print statements when I'm investigating a hypothesis – I'm no more likely to put them the right place than I would have put print statements.

And then there's a class of problems that neither debugger nor print statements will help: many years ago a very junior co-worker was wondering why his C code was giving the wrong answer for some math. It took me pointing out that one of the numeric types he was using in his code was different from the rest (I think it was #defined elsewhere, in some library, as an integer type). When the compiler did the math it had to do some type coercing.

Re: The unreasonable effectiveness of print debugging

#192
it works, its convenient, its easier to learn, easier to setup, it has less side effects in multithreaded programs meaning you can debug those too. You can even log to a file and then get these logs from your end users... The article does make a good point, errors that only cause failure a few hundred calls after the originating problem are easier to find this way too. Every few years I make an effort to learn to use whatever the current most popular debuggers are, but at the end of the day, its really just very specific kinds of errors that the debugging tools are better for finding and I generally go back to debug outputs soon enough.

Re: The unreasonable effectiveness of print debugging

#193
post #91
post #73

Probably the most interesting thing about development as a discipline is the near radio silence on how to debug. There is a decided lack of academic success in engaging with debugging as an object that can be studied. There are channels to learn about debugging as a stand-alone topic. Programmers don't often talk about debugging techniques in my experience. For something that takes up the overwhelming bulk of a devel…

Debugging is impossibly difficult to teach. It's much closer to "how to solve an escape room" than it is to "how to build X". Debugging requires deep understanding what you are doing and your system. It's different every time. And while there's a general algorithm you can follow: 1. Guess what's wrong 2. Ask "How would I prove that's wrong?" 3. Try it 4. If bug found, fix, if not go back to 1 How would you teach that…

It feels like there are basic heuristics that too often people either don't know or forget to apply.

I recommend http://debuggingrules.com/ - it's a good book that lays out some rules that have always helped me. When people come to me for help debugging something, invariably they've skipped some of these concepts, and applying them usually gets to the bottom of things faster than randomly changing things (which seems to be a common, but ineffective, way to debug a problem).

    UNDERSTAND THE SYSTEM
    MAKE IT FAIL
    QUIT THINKING AND LOOK
    DIVIDE AND CONQUER
    CHANGE ONE THING AT A TIME
    KEEP AN AUDIT TRAIL
    CHECK THE PLUG
    GET A FRESH VIEW
    IF YOU DIDN’T FIX IT, IT AIN’T FIXED

Re: The unreasonable effectiveness of print debugging

#194

Earlier quoted context omitted.

> And I've also cringed watching ninjas step through code slowly, reading everything, spending 20 mins catching something 2 print statements would have achieved. The problem is that the two print statements will only catch the bug if they are the right two, based on a correct hypothesis of what the bug is. Which, with a debugger, won’t require stepping, but setting two breakpoints, doing a run-to-breakpoint, and insp…

But with print statements if the first place I put them doesn't work, I can start doing bisects and quickly find the right place to print. As you note, debugger breakpoints aren't magically better than print statements when I'm investigating a hypothesis – I'm no more likely to put them the right place than I would have put print statements. And then there's a class of problems that neither debugger nor print stateme…

> And then there's a class of problems that neither debugger nor print statements will help: many years ago a very junior co-worker was wondering why his C code was giving the wrong answer for some math. It took me pointing out that one of the numeric types he was using in his code was different from the rest

A debugger and watches on the values of concern absolutely will help with that (so will properly placed print statements), so its a really bad example. (Of course, strong typing helps even more with that particular case.)

Re: The unreasonable effectiveness of print debugging

#195
I've not figured out a way to effectively debug a distributed system except via printf. Debuggers are basically a nonstarter, because stopping one component to inspect it almost always triggers knock-on effects in other components that change the overall state of the system.

Re: The unreasonable effectiveness of print debugging

#196
post #91
post #73

Probably the most interesting thing about development as a discipline is the near radio silence on how to debug. There is a decided lack of academic success in engaging with debugging as an object that can be studied. There are channels to learn about debugging as a stand-alone topic. Programmers don't often talk about debugging techniques in my experience. For something that takes up the overwhelming bulk of a devel…

Debugging is impossibly difficult to teach. It's much closer to "how to solve an escape room" than it is to "how to build X". Debugging requires deep understanding what you are doing and your system. It's different every time. And while there's a general algorithm you can follow: 1. Guess what's wrong 2. Ask "How would I prove that's wrong?" 3. Try it 4. If bug found, fix, if not go back to 1 How would you teach that…

There's also:

1. Pick a spot in the code

2. Figure out what you expect the state to be there

3. Check and see that the actual state matches

You can kinda binary search your way to the location of a bug by looking in different places

Re: The unreasonable effectiveness of print debugging

#197

Speed of iteration beats quality of iteration. You can step through the program, reason about what's going on, tracking values as they change. But if you missed the moment, you have start again from the beginning (time traveling debuggers being rare). Or maybe you're looking at the wrong part entirely at this stage, and just wasting time. With print debugging you write a bit of code to test a hypothesis. Then you run…

> Speed of iteration beats quality of iteration.

Right. That’s why printf debugging sucks.

If you’re in a compiled language with a 2-minute iteration it can take an hour to do a binary search to track down an issue that would take 5 minutes with a proper step debugger.

Print debugging is great because it works and is the ultimate fallback. But it sucks and I hate when I am forced to use it.

Re: The unreasonable effectiveness of print debugging

#198

In my experience, people who downplay debuggers don’t have the option to use effective debuggers. Debugging C++ and especially C# in Visual Studio is wonderful. Debugging Java in Eclipse can be great. Meanwhile GDB and most other language debuggers are painful and every IDE integration I’ve seen of them has been horribly unreliable. I’ve heard there’s a culture in parts of Google where kids go through uni using GDB b…

The Visual Studio debugger is great, but there are some limitations. Anything very serious is going to be multithreaded, and if you block a thread poking in the debugger, other things are going to start timing out and the real flow of the program is interrupted and impossible to reproduce.

Log heavily, and log systematically - imagine you're going to need to grep through days of logfiles to find the needle in the haystack - you will eventually. Build in runtime switches to dial log verbosity up and down. Err on the side of providing more context than less. If something throws exceptions, catch them, log exactly where it was, what it was supposed to be doing, and any relevant parameters or state.

If you can get them, process dump files are unreasonably effective, too.

Re: The unreasonable effectiveness of print debugging

#199
post #159

I feel like the author gets close to the point but fails to drive it home: step-through debugging is unbelievably cumbersome. During a typical step-through debugging session, 90% of the time is spent on lines you are completely not interested in. Oh, did you accidentally skip the important point because of how tedious it was to keep spamming step-over/step-in? Better start over again. With print debugging, you set up…

With lldb you can do that, basically you have the option of running commands when a given breakpoint is hit, so you can just make it place another breakpoint, and it will be placed only if the first breakpoint is hit. I assume you can do something like this on gdb as well.
Post reply on HN