Hacker News new | ask | show | jobs
by purerandomness 1912 days ago
How is changing code simpler than literally clicking on the line number to set a breakpoint?
5 comments

You said "click", I need to leave my keyboard.

Generally when I am coding I auto-run the tests on save. This means that to printf-debug I just add a message or two (and if I am coding I might already have a couple of useful ones lying around) and save. Then in less than a second I have a trace trough my program in the terminal. If I want to inspect a different variable I just add another print and run again.

With a debugger I need to kill my auto-run command, run the program, set breakpoints, type to see what variables I want to inspect, maybe switch stack frames, maybe step through a bit.

In my mind printf is like an automated debugger. I just put the info I want to see into the program and it does all of the printing for me. And when I find the problem I can just fix it and I am back to my edit-test cycle.

I'm not saying that there are no use cases for a debugger. For example I find variable-modification breakpoints very useful. As you mentioned if your edit-run cycle is slow then it may be faster to inspect a new variable in the debugger than adding another print statement. But when I just want to inspect values in my program I find printf sufficient and lower overhead. I'm sure part of my problem is that because I rarely use a debugger I am not as efficient, but I also think that printf-debugging is a very effective workflow for a wide variety of issues.

You said "click", I need to leave my keyboard.

Every proper IDE has a keyboard shortcut for that though.

With a debugger I need to kill my auto-run command, run the program, set breakpoints, type to see what variables I want to inspect

This indeed falls under your 'part of my problem is that because I rarely use a debugger' statement. E.g you could set breakpoints before you save, use auto-debug instead (i.e. launch program under the debugger on save instead of just rnning it - without breakpoints there shouldn't be much of a difference unless it's one of those nasty multithreading bugs), add variables you want to see to the watch window. Or type them anyway if it's a one-time thing. Or use tracepoints. Etc.

I personally keep bouncing back and forth between debugger and printing. All depends on context, but it's definitely worth it getting to know both really well.

So basically tracepoints, without touching the program code.
But I'm already mucking with the program code most of the time so I'm not worried about touching it.
When I use a debugger I often feel like I'm looking through a soda straw. I can only see the state at that one instance in time. Just because I know the line of code where the exception occurred, doesn't tell me which data caused it, and breaking on exceptions is often too late. Instead I'm stuck hitting continue over and over until I finally see something out of place, realize I went to far and have to start over again. With logging, I have the entire history at my fingertips which I can skim or grep to quickly pinpoint the data that caused things to go wrong.

More fairly, it is a trade-off with the debugger giving wide visibility into state, but narrow visibility temporally, and logging giving narrow visibility into state (just what you logged), but broad temporal visibility. They both have their place, but I find that logging narrows things down more quickly, while the debugger helps me understand the problem by walking through step-by-step, assuming the problem isn't obvious once narrowed down.

Would be nice if instead of break points debuggers had log points which stored the values of variables at that point in time. This data can be displayed as a table later.
You might be interested in Pernosco: see https://pernos.co/about/overview/ and its related content.

We agree with your critique of traditional debuggers and Pernosco tackles that "temporal visibility" problem head on.

I more or less agree; but I find myself wondering why I so often use Matlab's debugger, but almost never use pdb for python. It is not like I'm not used to using command line tools (I use bash, git, emacs, etc. everyday). It could just be an accident of habit, I don't know.
Depending on how complex your debugger is, it allows you to output values that might not be inspectable through the debugger. Especially computed values.

Debug printing also allows you to debug programs running in environments where you can't attach a debugger. For example, maybe halting the program causes the bug not to trigger. Or it's a remote system where you cannot attach a debugger for various reasons. Or the bug only happens in the optimized build, which in say C/C++ can make it quite tedious to walk through with a debugger.

Most of the time though I use print as "proactive debugging". Having detailed logs available is gold when customer calls with a blocking issue.

Especially computed values

Showing function return values automatically was really an eye-opener when I first encountered it.

Most OS offer that with process tracing like ETW and DTrace.
You have to first configure your IDE/editor to allow you debugging. This is different for every programming language/environment. Print works in any language without prior configuration.
In the time it takes me to figure out how to connect a debugger to the process I've had a good half-dozen full loops of 1) add print statements 2) compile 3) run already done.