Hacker News new | ask | show | jobs
by the-alt-one 1616 days ago
How quickly do you guys whip out the debugger when you encounter a bug?

I often can figure it out by reading the code (I'm the quickest jump-to-source in the wild west!) quicker than I can from inserting print stmts or hooking up a debugger.

I've also decided that I dislike having my IDE be my debugger, I prefer having an entirely separate UI for that. Maybe this is because I use Emacs and DAP mode and gdb is quite poor there, I'd rather use something like gdbgui.

4 comments

I suspect this will be controversial, but I read TPOP at a young age and I think it still summarizes my overall view. The quote from the article continues:

Blind probing with a debugger is not likely to be productive. It is more helpful to use the debugger to discover the state of the program when it fails, then think about how the failure could have happened. Debuggers can be arcane and difficult programs, and especially for beginners may provide more confusion than help. If you ask the wrong question, they will probably give you an answer, but you may not know it's misleading.

In the ~15 years since I read this I've seen dozens of colleagues try to use a debugger in place of thinking harder, and it never goes well. Sometimes, but much more rarely, I see someone use a debugger after thinking hard for a while. That usually goes excellently, and probably creates some unrealistic view of the tool's effectiveness because other programmers see the debugger and not the thinking. 99% of problems are solved during the "think harder" stage, and if I can't think my way out of some local problem I probably wrote too-complicated code anyway. (And if it's a non-local problem, the debugger may not help too much.)

The goal of most IDEs seems to be first help with a debugger / executing code/tests, second help with writing code, and only thirdly help with reading code. The older I get, the more those priorities seem inverted to me.

>The goal of most IDEs seems to be first help with a debugger / executing code/tests, second help with writing code, and only thirdly help with reading code. The older I get, the more those priorities seem inverted to me.

I'd be interested in developing more tools based on abstract interpretation and symbolic execution of the programs themselves and generally be able to query your tools more.

For example, let's say that you find a program state with the debugger which is invalid, the next question is then "How can this function reach this state?". This can be answered by the symbolic execution engine, giving you a function-local path. Then you can look at the callers of this function and ask the engine to do the same resolution on that level.

Being able to formulate questions and have them answered would lead to a question/reply-driven method of working, which I think would be very helpful.

> The goal of most IDEs seems to be first help with a debugger / executing code/tests, second help with writing code

We must not be using the same IDEs. To me “IDE functionality” is almost synonymous with “code navigation”: jump to definition, find references, etc., which are purely “code reading” features.

What do you mean by TPOP?
The book mentioned in the post; The Practice of Programming by Kernigham and Pike.
I stare hard at the code to build a mental image of what it's doing. I then use logs to check if what I think is happening is actually happening (including logging a stack trace when I want to make sure how the program gets there.)

I tend to use a debugger when I start to log too many things. It's a sign I should use a debugger to run the code, stop the execution where I'd put the logs and then explore the context and stack trace.

I also use Emacs (I'm mainly a Scala dev) and still fire up Intellij for debugging most of the time.

It's my first port of call, as it's rare for me to run the code I'm working on outside the debugger. So if anything goes wrong, it's there. If nothing else I can set a breakpoint or two to check that particular points are being reached, and have a look at some variables to see if there's anything obvious.

Also very good for crashes or asserts or whatever. The offending line, and the stack trace, are shown immediately.

I only use the debugger when I'm really lost or when I'm suspecting compiler/inheritance/indirection shenanigans. Most of the time I try to add logging/tracing because those are reusable and can help me debug other issues later, and just the action of actively thinking where to put them and why often points me to the bug and the possible fix.