Live data from Hacker News

Why I use a debugger

blog.pnkfx.org

61–70 of 80 posts

Re: Why I use a debugger

#61
post #47

I am surprised to find in these comments that using the debugger routinely and by default isn't a popular idea. I couldn't do my job as well as I do without having the reflex to use the debugger. I shouldn't be surprised though, the last time I watched a coworker roll his face on the keyboard trying to debug something the conversation went something like: - Me: Just use the debugger... - Him: But it's hard and annoyi…

I don't use a debugger routinely and by default. First reflex is to add logging, telemetry or tests because those are useful when another issue pops in a similar place: instead of attaching a debugger (which might alter the program flow/timings), recreating the flow (which may or may not be easy) and setting breakpoints, I just read the data that I already have, which usually guides me (or other coworkers) in the debugging.

For me, the debugger only comes out when those tools don't work quickly, I'm pretty lost or I'm inspecting the code flow of third party code.

Re: Why I use a debugger

#62
When I write code that has multiple, interrelated parts, before I ever run it I step through it in the debugger to verify that my logic is correct, I didn't make any off-by-one errors, library calls return what I expect, etc.

I especially do this when the code has destructive side-effects (a file gets moved/deleted, a database get updated, whatever), so I can skip over any external actions I don't actually want to occur until I'm ready for a full test run.

Everybody does this, right? Right???

Re: Why I use a debugger

#63

When I write code that has multiple, interrelated parts, before I ever run it I step through it in the debugger to verify that my logic is correct, I didn't make any off-by-one errors, library calls return what I expect, etc. I especially do this when the code has destructive side-effects (a file gets moved/deleted, a database get updated, whatever), so I can skip over any external actions I don't actually want to oc…

> I especially do this when the code has destructive side-effects (a file gets moved/deleted, a database get updated, whatever), so I can skip over any external actions I don't actually want to occur until I'm ready for a full test run.

I always wrap these statements in a function/if-statement/similar thing that allows me to run the tool in "dry mode" so changes are not done but just logged. It's pretty useful because I can reuse that mode whenever I want without reattaching the debugger and stepping again through everything.

Re: Why I use a debugger

#64

Earlier quoted context omitted.

It really depends on a lot of things. Debuggers can completely throw off timing, concealing the bug you're after. Debuggers may tell you that your program state is messed up (doh, sure), but not how you got there. Figuring out how you got there isn't necessarily any easier with a debugger than with generous logging. If anything, it can be much harder. Figuring out where exactly to break or which particular instance o…

> Figuring out how you got there isn't necessarily any easier with a debugger than with generous logging. If anything, it can be much harder. Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. This will even happen if the code which breaks the state is a me…

> Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state.

Knowing which part of the state messed up is like 90% of the debugging. Most of the time the part of the state you see messed up is like that because another part of the state is also messed up. Given that neither debuggers nor logging can go back in time to backtrack the state (well, time travel debuggers exist but aren't common or cover all cases), it's usually faster to inspect the code manually to try to find the original bug instead of re-running continuously to backtrack the state.

Re: Why I use a debugger

#65
post #36

Earlier quoted context omitted.

Allow me to doubt that this is possible on a regular basis. Anyone can get bouts of error-free code. It happens on a regular basis that I write dozens of lines of code and everything just works, without any debugging. However, it's not just the code you write, there are also bugs in code that someone wrote 5 years ago. Or a bug in a library that you have no idea about. A lot of times, these can be solved with a debug…

"Doesn't need debugger" isn't same as "error-free code." You can solve bugs by thinking about / reading code. I'd say that's the way I solve the vast majority of my bugs. Also "using a debugger" and "debugging" are not synonymous.

Thinking/reasoning about code is my main approach to finding and preventing bugs, and I would argue that it is by far the most important way to do so, since it is one of few ways to understand the ideas that lie behind the code as written, and to build a theory/mental model of what happens.

Still, there are cases where you will build a mental model that is wrong either due to minor bugs or larger design problems.

As a former physicist, I think of this like theoretical vs experimental physics. First you build the theory (by reviewing the code), then you run experiments (by first running the code). If you encounter surprises, you run more detailed experiements to pinpoint where your theory is wrong, and for this you can use print/log statements and/or a debugger.

In my experience, print/log statements are ok for relatively linear logic (immutable or functional patterns, for instance in a data pipeline), while the debugger may be more helpful for highly non-sequential patterns, where it is difficult to grasp what states the program may end up in (complex state machines driven by random/user input, for instance).

Then there are cases that are complicated by asynchronous, often high frequency input or that involves third party services that you cannot control (ie trading systems, logistics systems and similar systems that use a lot of concurrent transaction management, and are often connected to external systems, or even generic software like OS's, database engines, etc). Those may be impossible to reproduce properly in a debugger, and may instead need some kind of statistical approach, by bombarding the software with either live or synthetic input, and use collected metrics to build a theory that can explain the problem. (Which will trigger further experiments to validate.)

Depending on what software you are writing, using a debugger can be anything from a superpower to nearly useless.

The ability to reason about code, on the other hand, is universally useful. Arguably even for commercial software where you do not have access to the code. (As a physicist, I could not "see" quarks directly, but I could still detect them statistically by properly designed experiments.)

Re: Why I use a debugger

#66
post #53

Earlier quoted context omitted.

Whatever works for you man, but if you spend two plus weeks on a bug in a if statement that would've been obvious at a first glance with a debugger, I'm not going to feel like we are contributing at the same level. It's like we are tasked with digging a ditch together and you want to use a tea spoon instead of a shovel.

I can appreciate the teaspoon/shovel metaphor, which I've gotten a lot of mileage from myself—not necessarily always related to programming—but "a bug in a if statement that would've been obvious at a first glance with a debugger" does not reflect how debuggers actually work. Signed, Someone who actually likes debuggers but doesn't see you making a solid case for them at all.

I suspect GP was referring to a situation where you’re stepping though some problem code and see that you end up in the wrong clause or an IF statement?

Agree that’s not the first use case I’d think of, but I do think debuggers can quickly pinpoint that kind of thing as you step through code… if you know roughly where the problem is.

Re: Why I use a debugger

#67

Earlier quoted context omitted.

> Figuring out how you got there isn't necessarily any easier with a debugger than with generous logging. If anything, it can be much harder. Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. This will even happen if the code which breaks the state is a me…

> Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. Except when you find the data you're after doesn't exist early at startup, it's allocated on the fly as connections come and go, and you need thousands of connections to come and go before the bug manifes…

Indeed, it can happen too. All software is different, bugs are different, and optimal debugging tactics is very different as well.

But when the one in my comment does work, the saved debugging time can be measured in days.

Speaking about debugging tactics, there’re way more than just two. There’re OS-level tools like process monitor on Windows / strace on Linux. There’re specialized tools like RenderDoc or Wireshark. For different types of bugs, these tools can sometimes also save days of work compared to other methods.

Re: Why I use a debugger

#68

I thought using debuggers was standard practice in non trivial programs?

You probably were not born last time I fired a debugger. Those who can't code, debug. :-) Joke apart it's a style thing, tracing and thinking gets you a long way, though virtuoso debugger users can be productive too no doubt. It's a bit like GUI vs CLI.

You are thinking while you debug. It just gives you more to think about.

Re: Why I use a debugger

#69

Earlier quoted context omitted.

> Figuring out how you got there isn't necessarily any easier with a debugger than with generous logging. If anything, it can be much harder. Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. This will even happen if the code which breaks the state is a me…

> Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. Knowing which part of the state messed up is like 90% of the debugging. Most of the time the part of the state you see messed up is like that because another part of the state is also messed up. Given tha…

> it's usually faster to inspect the code manually

I’m not sure how usual that is. Sometimes “the code” is too many thousands of lines to inspect. Other times, “the code” is only the machine code but not the source code, inspecting megabytes of disassembly is not fun.

Re: Why I use a debugger

#70

Earlier quoted context omitted.

> Put a breakpoint early on startup, once hit put a data breakpoint on the part of the state which messed up, reproduce the bug, and there's very high chance debugger will take you to the code which broke the state. Except when you find the data you're after doesn't exist early at startup, it's allocated on the fly as connections come and go, and you need thousands of connections to come and go before the bug manifes…

Indeed, it can happen too. All software is different, bugs are different, and optimal debugging tactics is very different as well. But when the one in my comment does work, the saved debugging time can be measured in days . Speaking about debugging tactics, there’re way more than just two. There’re OS-level tools like process monitor on Windows / strace on Linux. There’re specialized tools like RenderDoc or Wireshark…

Aye. It's also not always obvious what's the optimal tactic, and I believe in many cases there are multiple equally valid approaches and you pick the one you feel most comfortable with. Sometimes the one you start with is a dead end.

That's why I don't really like an absolutist stance (if you rarely use debugger you're dumb / if you always poke around with a debugger you're dumb). I just happen to fall in the "rarely uses debugger" camp myself.

> I’ve done hundreds of interviews like this, and it’s fascinating watching what people do. Do they read the code first? Fire up a debugger? Add print statements and binary search by hand? [..] After hundreds of interviews I still couldn’t tell you which approach is best.

(From https://news.ycombinator.com/item?id=29813036)

Post reply on HN