There were quite a few reactions to my previous entry.  I’d like to add a few comments of my own.

First of all, Rob wrote:

[Debuggers are] a little *too* clever sometimes. A print statement does not (usually) interrupt the flow of execution. A breakpoint does.

That’s why the best way to do this with a debugger is to install a watchpoint at a location and do a println there. It won’t stop the code but it will print your debug code. No interruption, no spurious println in your code and the exact effect you were waiting for.

Have you ever blown an hour or two debugging the right code > in the wrong context because you didn’t realize that the breakpoint would get hit more than once, and so you used the first hit instead of the 17th?

Sure, the very first time I used a debugger. About 20 years ago 🙂

Besides, good luck finding the 17th println in your console.

At least, I can tell a debugger to stop the 17th time the breakpoint is hit. With your method, I need to discard manually and visually the first 16 println.

Mike said:

Cedric, I completely disagree with just about everything you say here. I find debuggers are enormous time wasters, and often cause enormous ancillary problems – timeouts, missing multi-threading problems, etc.

The big problems with debuggers are very well capured in "The Practice of Programming". Debug sessions are ephemeral, and they suck in mult-request/multi-thread environments. Debuggers can’t generally be used to diagnose production problems in-flight.

While this is true, I am having a hard time seeing how debuggers fall shorter than println debugging for this kind of task.

As for the ephemeral aspect, yes, but fixing a bug is also by nature, ephemeral. A debugging session might end up in one or several fixes, which you might want to capture in a regression test once you are done.

That’s why I really don’t understand people who say "don’t use debuggers, use unit tests". If you only use one of these two tools, you are not doing your job correctly. They are complementary.

In an ideal world, every developer uses test-driven development or at least writes regression or unit tests for any bug they fix and feature they add. In my world, you can never convince most developers to write a test to save their life, but at least, they understand the importance of finding bugs.

When you’re running your code through a debugger, what you’re seeing is the code right now in certain paths at it exists at that moment.

True, and once again, how is that different from a line in a log file?

Think interfaces and factories with pluggable backends, and you can see that understand the underlying design in detail, in your head, is far more important than being able to stumble through a debug session – because that session is only a brief moment in time. Not that I advocate something so primitive as println’s – use a logging package, for shrike’s sake!

No difference in my mind, you are just using a different API with more powerful output capabilities. Which is still missing the point.

As a final note – debug sessions do not help the poor slob who next has to debug the code – again because a debug session is ephemeral. Stop wasting your time in a debug, and craft logging information that will far outlast the current version (and possibly even outlast you!).

I have certainly never said that debugging should replace logging, which is yet another orthogonal issue.

In my opinion, a good developers uses:

  • A debugger
  • Logging
  • Tests

As I a said above, if you are not using these three tools, your productivity is not as high as it could be.