?
The unreasonable effectiveness of print debugging
251–260 of 366 posts
Re: The unreasonable effectiveness of print debugging
#252- cross language/platform
- forces you to come up with hypothesis up front, then test these very systematically
- you know what you are doing
- debugger doesnt interfere
- works across threads and processes
Re: The unreasonable effectiveness of print debugging
#253I can just write print(whatever) and get the job done, I don't want to put breakpoints and search for a data structure I need. Why can't I write something like this: breakpoint { debug(var) } ?
I use debuggers even for print-debugging for this kind of reason. No need to re-compile between changing prints, just re-run - the debugger session will hold them from previous runs, you can temporarily disable them with a single click, etc. It's FAR faster and more flexible.
Re: The unreasonable effectiveness of print debugging
#254Earlier quoted context omitted.
This is a lot of words but I wonder if you've ever worked with a debugger with watchable variables or immediate mode code execution. I find it odd you say print debugging is more flexible.
Using a debugger is largely passive - it shows you what is actually happening. Debugging via print allows you to step outside and peer in ie it is active . Print debugging can be prone to bugs within itself which may cause additional ignorance about the potential bugs being diagnosed. How meta can you get? 8) There's also the effect of the effort of actually looking - that may or may not have an effect. Anyway, the d…
Re: The unreasonable effectiveness of print debugging
#255Record-and-replay debuggers like rr [0] (disclaimer: I started and help maintain it), Undo, TTD, replay.io, etc address one set of problems. You don't have to stop the program; you can examine history without rerunning the program.
Pernosco [1] (disclaimer: also my baby) goes much further. Complaints about step debuggers (even record-and-replay debuggers) only showing you one point in time are absolutely right, so Pernosco implements omniscient debugging: we precompute all program states and implement some novel visualizations of how program state changes over time. One of our primary goals (mostly achieved, I think) is that developers should never feel the need to "step" to build up a mental picture of state evolution. One way we do this is by supporting a form of "interactive print debugging" [2].
Once you buy into omniscient debugging a world of riches opens to you. For example omniscient debuggers like Pernosco let you track dataflow backwards in time [3], a debugging superpower print debugging can't touch.
rr, Pernosco and similar tools can't be used by everyone yet. A lot of engineering work is required to support more languages and operating systems, lower overhead, etc. But it's important to keep in mind that the level of investment in these tools to date has been incredibly low, basically just a handful of startups and destitute open source projects. If the software industry took debugging seriously --- instead of just grumbling about the tools and reverting to print debugging (or, at best, building a polished implementation of the features debuggers have had since the 1980s) --- and invested accordingly we could make enormous strides.
[1] https://pernos.co/about/overview
Re: The unreasonable effectiveness of print debugging
#256Earlier quoted context omitted.
> Like I said, different tools for different uses, and really depends on the context We totally agree, and I'm not sure what we're arguing about--perhaps you can fill me in. I'm arguing that print is almost always worse than any specialized tool. (After all, who would use a specialized tool worse than print?) There is not a one-size-fits-all tool, and print is not a one-size-fits-all tool. Indeed almost every seasone…
I think we're mostly arguing about how useful the various approaches are. At least for me print debugging is a measure of last resort unless I want to extract some historical data out and I know it won't influence the timing of the issue I'm trying to chase down. With print debugging your inserting the whole build + deploy + repro setup loop into your debugging, if that's a long time(say 20 minutes in one job I had w…
Ah, that's fair.
> At least for me print debugging is a measure of last resort
Right, and I think this depends on the domain. For lots of mature environments, this makes sense -- there's been years for tooling to catch up to the kinds of bugs people run into, possibly corporate money being put into developing debugging tools, etc.
> IMO you should relentlessly optimize your iteration times, that's the inner loop of development speed and[...]
Agreed, though the effect on print debugging on iteration time is very environment-dependent.
> [...]print debugging fares pretty poorly in that area for all the reasons above
Adding console.log to a web app can be a trivial change (though of course reproducing app state is another issue) -- again very environment-dependent.
Re: The unreasonable effectiveness of print debugging
#257Whenever this comes up, I think of this quote from The Practice of Programming by Brian W. Kernighan and Rob Pike [0]: > As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding o…
Circa 1999, one would assume that Brian Kernighan and Rob Pike are largely drawing experience from working with C, which is a relatively verbose language. Single stepping through C code in a debugger is indeed a laborious process.
If you read accounts from Smalltalk developers, on the other hand, it's clear that they very nearly live their entire lives inside the debugger, and consider it to be an enormous productivity booster.
I would guess that there are several effects going on there. One would be that, in terms of how much effective work it accomplishes, a line of Smalltalk code is generally not equivalent to a line of C code. That has a big impact on just how many steps are involved in single-stepping your way through a region. The other is the nature of the debugger itself. Gdb and Smalltalk debuggers are wildly different pieces of software.
Re: The unreasonable effectiveness of print debugging
#258Earlier quoted context omitted.
Print debugging always works, but also: it lets the programmer customize their view of the program’s (very, very large) hidden state in any way imaginable. Step debuggers are the “no-code” equivalent: extremely useful for the purposes for which they were designed—and often the better choice there—but inherently limited. Geoff’s not wrong in invoking Bret Victor’s Learnable Programming argument that being able to trac…
This is a lot of words but I wonder if you've ever worked with a debugger with watchable variables or immediate mode code execution. I find it odd you say print debugging is more flexible.
I'm not making the argument that people shouldn't use debuggers -- obviously if there's a good one that does what you need, it'd be silly not to use it. And good debuggers are great.
But what happens when you're working on a distributed system? Or multiple processes on a single system? Or...etc. etc. -- debuggers are almost always built to support a particular set of use cases for a particular set of domains. Step outside, and they're not usually as useful.
print always works. It's almost never the best. It's more flexible because it can almost always be used.
Re: The unreasonable effectiveness of print debugging
#259Whenever this comes up, I think of this quote from The Practice of Programming by Brian W. Kernighan and Rob Pike [0]: > As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding o…
There's a part of me that wants to say that that opinion has to be taken with a grain of salt and a lump of paying attention to who is offering it. Circa 1999, one would assume that Brian Kernighan and Rob Pike are largely drawing experience from working with C, which is a relatively verbose language. Single stepping through C code in a debugger is indeed a laborious process. If you read accounts from Smalltalk devel…
Re: The unreasonable effectiveness of print debugging
#260Whenever this comes up, I think of this quote from The Practice of Programming by Brian W. Kernighan and Rob Pike [0]: > As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding o…
There's a part of me that wants to say that that opinion has to be taken with a grain of salt and a lump of paying attention to who is offering it. Circa 1999, one would assume that Brian Kernighan and Rob Pike are largely drawing experience from working with C, which is a relatively verbose language. Single stepping through C code in a debugger is indeed a laborious process. If you read accounts from Smalltalk devel…
The core of his position (as I understand it) was that regularly needing a debugger is a sign that your software has "gotten away from you". You've let the software get to a state where it cannot easily be understood from the architecture and program text alone.
I do think debuggers can be useful when building up comprehension - particularly of other people's software.
It's very time consuming though, and at each "trace" you're only seeing one path through the program. Good architecture and documentation lets you understand all the possible paths at once.