Live data from Hacker News

Why I use a debugger

blog.pnkfx.org

51–60 of 80 posts

Re: Why I use a debugger

#51

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

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 memory corruption bug in different thread, in the code written in another language, from a third-party DLL.

> debuggers are nice for simple, borderline trivial programs where everything fits on a screen and there's a handful of variables to keep track of

It's funny I think it's the opposite. When there's only a few variables, one can print/log the complete state pretty often. When the state takes a gigabyte of memory and changes often, similar amount of logging going to produce too many terabytes of logs to be useful. Debugging is interactive, you can inspect the complete state and find the most relevant pieces to watch.

Re: Why I use a debugger

#52
post #8
post #3

Earlier quoted context omitted.

You'd think. But I still see discussions in JavaScript and PHP related threads where people swear by adding `console.log`/`var_dump` statements to their code over using the debugger. I've seen quite a few threads on r/php where individuals introduce a newer, supposedly better, library that can be used instead of `var_dump`, and there's always the inevitable "why not use the debugger?" to which many reply "because it'…

Which is strange, because debugging in JS and PHP is almost trivial to setup. Perhaps less so in PHP, but for JS it's right there in the browser for client side code.

JS is super straightforward until you're transpiling from a newer version of JS or from TypeScript and debugging is supported via source maps (which tends to be most JavaScript codebases). At that point, the debugging experience is pretty hit and miss. When it works it's fantastic, but it doesn't always work.

Re: Why I use a debugger

#53

Earlier quoted context omitted.

My point is that the debugger may help you understand the bug, but does not remove it. A better name for the tool would be something like bugfinder, or steprunner. > You don't click it, even out of desperation at any point in your career? I think I've never used an IDE since the (good) times of borland C++. > I get really tired and demotivated working with people who are like that You would probably hate working with…

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.

Re: Why I use a debugger

#54
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’ve found corporate software environments anathema to learning. The daily standup will not reward “yesterday I learned how to use a debugger” or “yesterday I spent time reading documentation” but it does reward “yesterday I spent hours grinding out the root cause of a bug”. There are other reasons, of course - but fundamentally the messaging is to get it done with as little learning as possible. You should know it all already! Learning, it should also be said, is very very hard when you are burnt out. And most of the learning capacity is used up learning non-transferable knowledge about internal-only APIs and systems you will never use again.

The solution is probably employer-funded sabbaticals but since those are rare people just settle for quitting and poking around at their own projects for a while.

Now that I’m more of what you’d call a “senior” developer I realize the absolute importance of taking time to set up your development environment so compiling, debugging, unit tests, prototyping etc. are as seamless as possible - the benefits to productivity and general happiness are manifold! But having the clout to invest more “non-productive” time upfront so your overall productivity is much higher is not usually afforded to devs fresh out of school who tend to just grind it out.

Re: Why I use a debugger

#55

Classic interview question. Tell me about the time you used a debugger to solve a programming issue. Saying "I don't use a debugger" is like saying to a C programmer "I don't use pointers". Cut the interview short. Thank them for their time then escort to the exit.

There are programmers that rarely need debuggers because they deeply think about the state of the program at every line of execution. I am not one of them but it is an amazing sight to see. And if they then use a debugger, they are in and out in a jiffy (usually).

That breaks as soon as the perfect code in your head has to interact with code someone else (typically and hopefully colleagues you can talk to) wrote.

Re: Why I use a debugger

#56

Earlier quoted context omitted.

> a bug in a if statement that would've been obvious at a first glance with a debugger If you already knew which if statement to look at, it's irrelevant whether you use a debugger or printf(). Actually, it becomes even less relevant when you have thousands of dynamically allocated objects running the same statement but only one of them goes wonky and you only know which one it is later at runtime. In the end you end…

> If you already knew which if statement to look at, it's irrelevant whether you use a debugger or printf(). That's exactly when it matters, when you don't know where the problem is. You have a big ball of spaghetti business logic and a customer object that is passing through it. At some point the customers total balance is screwed up. You can: - Read a lot of code and guess where that happens and set a printf or two…

Somehow we went from obvious at first glance to .. trace a variable and you find the problem eventually?

Now the question is, how do you tell from the trace that the total is wrong? If you can write a function to check it in the debugger, you probably can -- with roughly the same effort -- write an assert() or (asserts) in the program where that variable is modified, and that'll ensure you'll be immediately notified the next time it goes wrong even before anyone notices let alone has time to dig out a debugger. I'd say the value of creating asserts is up there with unit tests.

You can object that actually the problem is in the complicated business logic and is already gone by when the assert fires and the wrong value is finally assigned/updated to the variable, but that same problem would come up in a debugger too. At one point your debugger notices that whoops it's gone wrong, but you don't know how exactly how you got there? Like I said in another thread here, things like rr can really change debugging (allowing you to rewind time, sort of) when they become available to your platform & language, but until then, I just don't find very compelling arguments why inspecting bad state in business logic would be so much faster in a debugger than with printfs. I find debuggers useful mainly for some niche things (ok, which NULL or freed pointer did I dereference and segfault on?).

Now if you have to make an argument about performance, go ahead, but that's kind of orthogonal and it goes both ways. Some programs run too damn slow under a debugger, sometimes you have to make a separate build with debugging info and different build options (again possibly with a massive performance impact) and figure out how to use all that in conjunction with the target system that only has a few dozen megabytes of spare RAM.. if running a debugger requires none of that but builds are slow for you, go for it.

Re: Why I use a debugger

#57
post #8
post #3

Earlier quoted context omitted.

You'd think. But I still see discussions in JavaScript and PHP related threads where people swear by adding `console.log`/`var_dump` statements to their code over using the debugger. I've seen quite a few threads on r/php where individuals introduce a newer, supposedly better, library that can be used instead of `var_dump`, and there's always the inevitable "why not use the debugger?" to which many reply "because it'…

Which is strange, because debugging in JS and PHP is almost trivial to setup. Perhaps less so in PHP, but for JS it's right there in the browser for client side code.

For sure not trivial with php

Re: Why I use a debugger

#58

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 p…

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 espec…

What do you mean by TPOP?

Re: Why I use a debugger

#59
post #36

Earlier quoted context omitted.

There are programmers that rarely need debuggers because they deeply think about the state of the program at every line of execution. I am not one of them but it is an amazing sight to see. And if they then use a debugger, they are in and out in a jiffy (usually).

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…

In my experience, the hard bugs (KDE/Xfce memory leaks and use-after-free, PipeWire ID reuse race conditions between pipewire and pipewire-pulse and plasmashell and wireplumber) cannot "be solved with a debugger and a few WTFs". They occur in giant unfamiliar codebases, and solving them requires global understanding across modules (and sometimes over time, which gdb and somewhat rr are bad at). I spend days to weeks tracing code and taking notes (much as if I were learning the codebase) to actually understand it well enough to find the root cause (intended or violated assumptions and invariants, mismatches in different parts of the codebase, faulty reasoning), before I can hypothesize and implement fixes which aren't band-aid hacks.

I want a tool which takes a rr-like trace, then generates a trace of which functions call which other functions, and how work is divided between callers and callees, which loop iterations and branches are taken (which may be hundreds or thousands of pages long), then lets me subset the function calls or control flow I care about, as a starting point for me to take notes about a particular cross-cutting aspect (in the aspect-oriented programming sense, like "all calls to alsa-lib and all their call stacks" or "cross-thread shared memory accesses") or workflow (eg. startup and shutdown processes) of code execution.

I want a hybrid of architectural documentation (for implementers rather than users), personal notes, and a "debugger" for introspection/observability on code execution. I feel Pernosco aims to be the latter, and in my usage so far it's a poor choice for automating the tedium of building/codifying bird's-eye architectural understanding and global reasoning, but it might grow on me over time as a debugger for tracing data. (Functional programming promises to avoid the need for global reasoning, but I haven't looked into it.)

Re: Why I use a debugger

#60

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.

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 manifests, and the data that eventually gets messed up may first be used thousands of times before it's wrong all of a sudden. IME it's precisely these multi-threaded memory corruption bugs that really resist debuggers. And as is often the case, debugger changes timing so much that the bug doesn't even reproduce.

Even if you find the code that corrupts the memory, it might be totally okay, it just somehow got passed the wrong memory long ago through no fault of its own (or you're looking at a use-after-free).

Post reply on HN