Live data from Hacker News

What a good debugger can do

werat.dev

71–80 of 208 posts

Re: What a good debugger can do

#71
Thanks very much for posting this article. I found it very intriguing. I read it carefully but I didn’t visit all the links or watch all of the in-line videos.

I would say that for the most part I am a printf-style debugger. I remember reading some years ago (on HN, I believe) about time travel debugging in - I believe - C# and I was really impressed but I don’t code in C# so it soon left my mind.

I have a deep appreciation for mastering one’s toolset. I can’t think of the number of times that I learned something new about a tool (language, editor, shell, browser, whatever) that I use daily that changes my workflow - it has happened so many times. And as with all things code, sometimes new features are added.

I am going to try to make a point to re-read this article later and to visit each link and glean what I can.

I mostly code in Go. I wonder, does anybody know how much of this stuff might be supported there?

Re: What a good debugger can do

#72
post #71

Thanks very much for posting this article. I found it very intriguing. I read it carefully but I didn’t visit all the links or watch all of the in-line videos. I would say that for the most part I am a printf-style debugger. I remember reading some years ago (on HN, I believe) about time travel debugging in - I believe - C# and I was really impressed but I don’t code in C# so it soon left my mind. I have a deep appre…

For time travel debugging in Go:

The Delve debugger for Go supports debugging rr traces: https://github.com/go-delve/delve/blob/master/Documentation/...

Undo (who I work for) maintain a fork that debugs our LiveRecorder recordings: https://docs.undo.io/GoDelve.html

Either rr (https://rr-project.org/) or our UDB debugger (https://undo.io/solutions/products/udb/) can do some time travel debugging of Go programs via GDB's built-in support for Go. I believe its weakness is in support for goroutines, since they don't map well onto its idea of how programs run.

Re: What a good debugger can do

#73
post #31

a good debugger supports different kinds of breakpoints, offers rich data visualization capabilities, has a REPL for executing expressions, can show the dependencies between threads and control their execution, can pick up changes in the source code and apply them without restarting the program, can step through the code backward and rewind the program state to any point in history, and can even record the entire pro…

>can step through the code backward and rewind the program state to any point in history This seems impossible for anything that modifies external state. Say 1. Open database connection 2. Commit data 3. Close database connection How would you rewind right before #2 if you've already completed step #3? You'd need the socket/connection you already closed Unless that means something more like "keep a running record of…

Time travel debugging generally works on record-and-replay, with there being a lot of research into figuring out what you need to record to get deterministic replay. Recording the results of system calls is a necessary step [1] to get deterministic replay, and that lets you replay even things that rely on modifying external state like database connections.

[1] Necessary, but not sufficient. Multithreaded applications require a lot more care, and rr relies on very accurate hardware counters to get multithreaded executions working correctly (and not all hardware supports these hardware counters!).

Re: What a good debugger can do

#74

Just yesterday I was trying to dive into a container running some c program and I took a look at gdb... again, for the n time.. and the whole ordeal of the gdbserver and gdb as a client and the symbol table yadda yadda yadda I just rebuild the program with some printfs displaying data, filename and line number and re ran it. Done. gdb is stifling.

Have you tried using a Time Travel Debugger to record the process and then just debug the recording outside?

You can use rr or LiveRecorder (commercial product, which I work on) to generate the recording non-interactively then debug it "locally". Avoids the need to set up a client/server configuration, so long as you don't need to modify variable values at runtime, etc.

Re: What a good debugger can do

#75

This is what a good debugger can do: https://twitter.com/yiningkarlli/status/1628612150041382912 (Tomorrow Corporation)

Wow I'm just 5 mins into the video and this looks ridiculously powerful. This is essentially an integrated development environment for game development with everything every programmer dreams about!

How do I learn to make such tools? From what I heard everything in the video is built in-house including the language and compiler. Although I understand many game studios do similar stuffs this is by far the most impressive I heard about.

Re: What a good debugger can do

#76

I have mostly found the people who dismissed debuggers tended to be more Unix/Linux people, probably because raw gdb is such a huge pain to use. Windows developers and Visual Studio developers where the debugging experience is so easy, tend to sing the praises of debuggers. I wonder if it a bit of sour grape for the Unix/Linux crowd?

As much of a Linux zealot as I am, you make a valid point. In college, I had a TA help me debug a C program on a VAX, and he blew through finding the problem using its native debugger, and wouldn't explain what he did. (I had an O where a 0 should have been. Or vice versa. It was a worse problem back in the days of actual terminals. He found it in literally 30 seconds after I had been bashing my head on the printout for a couple hours.) Anyway, it took me probably 10 years of professional coding before I discovered gdb, and then realized what that TA had done. All at once, I realized how far you could get without an actual debugger, and also why he never bothered to try to explain it to me. I wasn't ready. Not by a long shot. Seeing the right-click options on breakpoints in Visual Studio was... revelatory.

Re: What a good debugger can do

#77

Earlier quoted context omitted.

Conditional breakpoints are supported for most dynamic languages. With static ones like c++ your way is the only practical way I believe

Visual Studio supports conditional and printing breakpoints for both C and C++. I tend to use them rarely because they really hurt performance, though. I only use them if I need to be able to turn them on and off at will, which hardcoded __debugbreak()s don't allow, obviously.

I helped implement fast conditional breakpoints in UDB (time travel debugger for Linux) - https://www.youtube.com/watch?v=gcHcGeeJHSA

We used GDB's conditional breakpoint bytecode https://sourceware.org/gdb/onlinedocs/gdb/General-Bytecode-D... to get a speedup in the thousands of times vs plain conditional breakpoints.

That works for us because we've got in-process agent code that can evaluate the breakpoint condition without trapping. It should be possible to do this in other debuggers with a bit of work, though we have the advantage of in-process virtualisation to help hide this computation from the process.

Re: What a good debugger can do

#78
post #44

Earlier quoted context omitted.

I'm very happy to hear it! Can you point me at a few of them?

Mentioned in TFA is "rr"; it serves up to gdb the history of the program and you can use tracepoints (also mentioned in TFA) to essentially retroactively add prints. Gdb is ... not particularly ergonomic, but it is eminently scriptable and writing programs to generate arbitrary logs post-facto is a useful skill. Undo is another one for Linux programs, and I think I've seen developers from them post here.

Hallo, I'm an Undo developer wave

Indeed, using GDB's version of tracepoints (dprintf - https://doc.ecoscentric.com/gnutools/doc/gdb/Dynamic-Printf....) is really powerful and replaying a trace with these installed is to generate "logs I wish I'd had" is exciting.

It also has potential use if:

* you'd like to diff two executions (e.g. one successful, one failing) - you probably can't just compare raw execution as there'll be uninteresting variation but comparing extended logs could be useful

* you are debugging something at a customer site - they might not let you debug directly but you could iterate on plain text logs by shipping them additional tracepoints to run on a recording

We thought this was useful enough that we implemented a tool with its own DSL for simply specifying post factor logging "probes": https://docs.undo.io/PostFailureLogging.html

Re: What a good debugger can do

#79

Just yesterday I was trying to dive into a container running some c program and I took a look at gdb... again, for the n time.. and the whole ordeal of the gdbserver and gdb as a client and the symbol table yadda yadda yadda I just rebuild the program with some printfs displaying data, filename and line number and re ran it. Done. gdb is stifling.

Containers are the real ordeal and not just here.

Re: What a good debugger can do

#80
post #31

a good debugger supports different kinds of breakpoints, offers rich data visualization capabilities, has a REPL for executing expressions, can show the dependencies between threads and control their execution, can pick up changes in the source code and apply them without restarting the program, can step through the code backward and rewind the program state to any point in history, and can even record the entire pro…

>can step through the code backward and rewind the program state to any point in history This seems impossible for anything that modifies external state. Say 1. Open database connection 2. Commit data 3. Close database connection How would you rewind right before #2 if you've already completed step #3? You'd need the socket/connection you already closed Unless that means something more like "keep a running record of…

> Say 1. Open database connection 2. Commit data 3. Close database connection > > How would you rewind right before #2 if you've already completed step #3? You'd need the socket/connection you already closed

The key thing is that you're really rewinding the world, as visible by the program

The program doesn't actually know what the network transaction with the database was, it just knows what syscalls it made and what results they returned. If, whenever it gets to talking with the database, you provide the same result as last time then it can't tell the database is gone.

This is self-supporting: if you do this consistently with external sources of information then the program will never go down any new code paths, guaranteeing that you'll always have a ready answer recorded when it needs it.

Post reply on HN