Whenever 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…
> we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places.
Uh, me too. That's why I don't single-step through huge chunks of a program.
The problem is that it's not just a matter of "learning the debugger for Java." In practice there are many different projects that configure debugging many different ways, and it doesn't matter that you know which keys to press in IntelliJ if it will take you an hour to figure out how to attach it to the project. This speaks to OP's point, where it's hard to use a real debugger to casually investigate random projects…
The java case is actually pretty universal ... you run the JVM with debugging enabled (fixed string of flags) and then tell your IDE to attach to the JVM on the port you gave it. You don't need compileable source, can be on a remote server, different OS etc - if you have just the source for the bit you want to debug you can set a breakpoint in it and it'll stop there. Being able to debug third party code in remote /…
The Java case is arguably the least difficult out there thanks to reasons you outline. But still, the other day I had to debug a Gradle plugin written in Java. It's possible! But it took an hour or so of effort to figure out which options to use and which program to give them to.
Almost all the reasons people use print debugging can be overcome by improving debuggers --- and to some extent already have been (in the words of William Gibson, the future is already here, it's just not evenly distributed yet). I think it's important for people to understand that the superiority of print debugging is contingent and, for many developers, will not persist. Record-and-replay debuggers like rr [0] (dis…
Post author here — just wanted to say I emphatically agree with this and have found your work on rr and Pernosco very inspiring! Anyone who hasn’t seen this work should check it out.
Personally, I think my biggest reason for using print debugging is.. it works. In C++ I often find the debugger doesn't find symbols on projects built with configure/Make. If I have a Java Gradle project I have no idea how to get it into a debugger. Python debuggers always seem fragile. Rust requires I install and use a "rust-gdb" script -- except on my current machine that doesn't work and I don't know why. I'm sure…
Python easily has the best debugger I've ever seen in a language. ``` import pdb; pdb.set_trace() ``` that's literally all you have to do at any point in your code. Run your code in the foreground of a terminal, and boom you have a debugger exactly where you want it.
Pry with Ruby allows you to drop in to a repl anywhere with binding.pry
You can edit the state and keep running after altering the program.
But usually I just end up printing a few things from the repl and figuring out what is fouled up.
Almost all the reasons people use print debugging can be overcome by improving debuggers --- and to some extent already have been (in the words of William Gibson, the future is already here, it's just not evenly distributed yet). I think it's important for people to understand that the superiority of print debugging is contingent and, for many developers, will not persist. Record-and-replay debuggers like rr [0] (dis…
> Almost all the reasons people use print debugging can be overcome by improving debuggers
The Python package PySnooper is pretty good for "fancy" print debug statements: https://github.com/cool-RR/pysnooper I've caught quite a few bugs using this show-me-all-locals() approach...
Whenever 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…
It also matters which debugger you are using and which features it has. I personally find gdb to be completely awful, while some IDE debuggers are a delightful. With Java, you can hotswap code into a running program. And you could write the majority of your program like that. It becomes an interactive experience a little bit similar to using a jupyter notebook.
You can also make a weird sort of UI this way, where the way you interact with your program is by changing the code / and or state while it's running. Breakpoints prompt for input.
Qt Creator debugger fails on me constantly, it's 2021 and the leading C++ plaf. is completely unreliable in that many more cases. That's why 'I must' use print debugging, because the 'powers that be' still provide a broken, half-baked solution 30 years in. Print debugging is however so powerful, I think there almost should be a mechanism built into languages and tooling around it so that it becomes part of the proces…
Have you tried Clion?
Well I just tried it and thanks for reminding me it was an option. I like it so far, we'll see how the debugger works, but IDE's cannot rid us of the cobwebs of arcane languages. C/C++ I think are the worst, the number of pitfalls and amount of needless complexity is byzantine and an enormous strain on mental energy.
I don't get the usefulness/effectiveness print debugging. I work in Ruby and JavaScript and I find it much more efficient to know the whole state of the world and the objects in it at a certain place, because I generally know where the problem may be. For example I use pry in ruby and the debugger; statement in JS.
Maybe it is just the way my brain works? I'd rather stop and see what I need behind a condition than have to filter through a lot of possibly unformatted console output.
There is a dimension that gets overlooked in these discussions: tests. Every bug should start with a mind set to create a new test: unit, integration, or end-to-end. These are regression tests. Now, whether the test is needed or not is a decision that will fall out the bug fix. There is a distinct difference between the skill of debugging and skill of writing tests. I focus most of my efforts in writing test code. Someday perhaps IDEs will be the test platform for all the test types. That's not today though. The question in my mind is not print debugging versus IDE, but test code debugging versus ad-hoc debugging. IDEs encourage ad hoc debugging because once a bug is fixed, the test code needs to be written from the ground up, a step this is often left out due to time limits. I debug in test code and when the debugging is done the test is written. This applies to new code as well and mirrors the paired programming notion of starting new development using test code.