Live data from Hacker News

Don’t look down on print debugging

blog.startifact.com

81–90 of 164 posts

Re: Don’t look down on print debugging

#81
post #59

While print-type debugging has a place, the reason there are a lot of articles dissuading the practice is the observed reality that people who lean on print debugging often have incomplete knowledge of the immense power of modern debugging tools. This isn't just an assumption I'm making: years of being in developer leadership roles, and then watching a couple of my own sons learning the practice, has shown me in hund…

Speaking from my own experience I'm not so sure that printf debuggers just have "incomplete knowledge [...] of modern debugging tools". I use printf (or the file-based equivalent, log files) quite a lot, but nobody can accuse me of not knowing good debugging environments. Also, what's "modern" about "Walk the call stack! See the parameters and values, add watches, set conditional breakpoints"? Those are all things we…

> So please refrain from calling people with different preferences uneducated.

OP said:

> … people who lean on print debugging often have incomplete knowledge of the immense power of modern debugging tools.

I am educated. I have a metric fuckton of incomplete knowledge in all areas of life.

You’re poking at something that wasn’t said.

Re: Don’t look down on print debugging

#82
I mostly use print debugging and not because i don't know how "real" debugging works. It's just that most of the code i deal with, deals with data that's flowing real time. So you stopped on a breakpoint, and the app broke already because incoming data and/or what consumes output, didn't stop.

The data streams of course can be simulated, then "true" debugging with breakpoints and watches becomes practical, but the simulation is never 100% and getting it close to 100% is sometimes harder than debugging the app out using print debugging. So with most of the code, i only use debugger to analyse crash dumps.

Re: Don’t look down on print debugging

#83
Esoteric: I use print debugging on a Lisp Machine using a presentation based Read Eval Print Loop (REPL), similar things would work in some other Common Lisp environments. Presentation based means that the REPL remembers all output and the objects associated with that output.

    (defmethod move ((a-ship object) (a-place port))
      ; do something
      )

    (defmethod move :around (what where)
      (print `(start moving object ,what to ,where))
      (call-next-method))
Above prints the list to the REPL. The REPL prints the list as data, with the objects WHAT and WHERE included. It remembers that a specific printed output is caused by some object. Later these objects can be inspected or one can call functions on them...

This combines print debug statements with introspection in a read-eval-print-loop (REPL).

Writing the output as :before/:around/:after methods or as advise statements, makes it later easier to remove all print output code, without changing the rest of the code. -> methods and advises can be removed from the code at runtime.

Re: Don’t look down on print debugging

#84
I like debuggers and use them when I can, but folks who say you should only use debuggers tend to not realize:

* Not all languages have good debuggers.

* It's not always possible to connect a debugger in the environment where the code runs.

* Builds don't always include debug symbols, and this can be very high-friction to change.

* Compilers sometimes optimize out the variable I'm interested in, making it impossible to see in a debugger. (Haskell is particularly bad about this)

* As another commenter mentioned, the delay introduced by a debugger can change the behavior in a way that prevents the bug. (E.g. a connection times out)

* In interpreted languages, debuggers can make the code painfully slow to run (think multiple minutes before the first breakpoint is hit).

One technique that is easier to do in printf debugging is comparing two implementations. If you have (or create) one known-good implementation and have a buggy implementation, you can change the code to run both implementations and print when there's a difference in the result (possibly with some logic to determine if results are equivalent, e.g. if the resulting lists are the same up to ordering).

Re: Don’t look down on print debugging

#85
post #33

I agree with the title that you shouldn't look down on print debugging. You should look down on people who are slow at fixing bugs and who refuse to try tooling to be able to keep pace -- and using print statements can sometimes be a marker of this. But print debugging is just a tool and has its place, and the use of print debugging is not itself an indicator of poor developer performance. If you can find/fix bugs as…

I find the people quick at fixing bugs are even quicker at introducing new bugs.

Re: Don’t look down on print debugging

#86

Print debugging is the tool most people reach for when they can, but its biggest problem is that you have to change the source code to add the printfs. This is impractical in many circumstances; it generally only works on your local machine. In particular, you can't do that in production environments, and that's where the most interesting debugging happens. Similarly, traditional debuggers are not available in produc…

How is side-eye different from dtrace?

Re: Don’t look down on print debugging

#87
post #49
post #16

Earlier quoted context omitted.

To be fair though: printing also will likely impact timing and can change concurrent behaviour as well. Still agree that print debugging is more useful in such situations (and I prefer it in general).

Yes, but you can repeat your print-debug-loop once a second, maybe even faster. Hit play and look at the output. Hit play again and see if it changed. It may or may not turn up the concurrency issue. Stepping through with a debugger will take you at least a minute per cycle, won't turn up the concurrency issue, and will spend a great deal of your daily concentration budget.

You can make your breakpoint conditional on the conditons you're looking for, then it'll run full speed until you hit the timing edge case.

Best of both worlds.

Re: Don’t look down on print debugging

#88
post #80

While print-type debugging has a place, the reason there are a lot of articles dissuading the practice is the observed reality that people who lean on print debugging often have incomplete knowledge of the immense power of modern debugging tools. This isn't just an assumption I'm making: years of being in developer leadership roles, and then watching a couple of my own sons learning the practice, has shown me in hund…

I’ve definitely seen an undercurrent of “I don’t need the crutch of a debugger” sort of attitudes online over the years, never really made sense to me. It can be painful pairing with someone who keeps adding print statements one at a time and repeating the 15 step process to get to them when they could have put in a breakpoint right out of the gate. I still print stuff plenty, but when the source of an issue is not i…

> It can be painful pairing with someone who keeps adding print statements one at a time and repeating the 15 step process to get to them when they could have put in a breakpoint right out of the gate.

This does sound painful, but this is not what most people who advocate for print debugging are advocating for.

If I'm only going to add one print statement, that's obviously a place where a breakpoint would serve. When I do print debugging, it's precisely because I haven't narrowed down the problem that far yet—I may have ten theories, not one, so I need ten log statements to test all ten theories at the same time.

Print debugging is most useful when the incorrect behavior could be in one of many pieces of a complex system, and you can use it to rapidly narrow down which of those pieces is actually the culprit.

Re: Don’t look down on print debugging

#89
post #49
post #16

Earlier quoted context omitted.

To be fair though: printing also will likely impact timing and can change concurrent behaviour as well. Still agree that print debugging is more useful in such situations (and I prefer it in general).

Yes, but you can repeat your print-debug-loop once a second, maybe even faster. Hit play and look at the output. Hit play again and see if it changed. It may or may not turn up the concurrency issue. Stepping through with a debugger will take you at least a minute per cycle, won't turn up the concurrency issue, and will spend a great deal of your daily concentration budget.

I think in this case, because everyone brings up multithreaded examples when saying a debugger isn’t useful, maybe print debugging can lead you towards the path of where to use a debugger efficiently.

I personally think if you can’t use a debugger in a multithreaded codebase, the architecture is bad or one doesn’t understand the code. So yeah, full circle, if print debugging helps one learn the code better, that is only a positive.

I’m so amused about how debuggers have become a debate around here. “Printf vs debugger” is like “emacs vs vi” right now, and it really shouldn’t be. Sometimes I put a breakpoint AT my printf statement.

Re: Don’t look down on print debugging

#90

Debugger vs print? No, the most smug response to that debate I ever heard was "Neither, I use unit tests".

I've heard that too - I've never had the good fortune to with on a codebase where the was practical though.

I've never satisfied myself that you can't just make a legacy codebase work that way, given enough effort, but I am not fully convinced it's always a good idea.

Post reply on HN