Debugging with GDB
sourceware.org
sourceware.org
Even if the problem only occurs one time in a thousand, if you have recorded it then you can review it in arbitrary detail as many times as you need. You can even send the recording to another developer for their feedback.
Probably the second best thing about time travel is watchpoints[0] + reverse-continue[1] - combining these two features, you can answer "why is that value there?" incredibly quickly.
Reverse execution + watchpoints is so powerful it can speed up the diagnosis of memory corruptions, race conditions, algorithmic bugs, etc from days/weeks to hours.
[0] https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.ht...
[1] https://sourceware.org/gdb/onlinedocs/gdb/Reverse-Execution.... - GDB has an implementation of reverse debugging but larger projects like `rr` (https://rr-project.org/) or `udb` (https://undo.io/solutions/products/udb/ - which, disclaimer, I work on) exist to do this with higher performance on complex, real-world programs.
(edit: format links better)
> Interactive debuggers include the ability to modify code and step forward based on updated information.[4] Reverse debugging tools allow users to step backwards in time through the steps that resulted in reaching a particular point in the program. Time traveling debuggers provide these features and also allow users to interact with the program, changing the history if desired, and watch how the program responds.[5]
https://github.com/rr-debugger/rr :
> System requirements: Linux kernel ≥ 3.11 is required (for PTRACE_SETSIGMASK).
> rr currently requires either:
> An Intel CPU with Nehalem (2010) or later microarchitecture. [OR] Certain AMD Zen or later processors
Is there an rr-like reverse time-travel debugging tool for ARM64/aarch64?
Are GUIs like Voltron and Ghidra helpful for gdb and/or rr-like traces?
Any gdb front end can probably be made to work with rr. Our current project is (shameless plug) https://pernos.co/ which provides a super-advanced GUI for working with (x86) rr traces.
rr (software) https://en.wikipedia.org/wiki/Rr_(debugging)
Record and replay debugging https://en.wikipedia.org/wiki/Record_and_replay_debugging
/? site:github.com inurl:awesome https://www.google.com/search?q=site%3Agithub.com+inurl%3Aaw...
Aside from `khuey`'s comment (https://news.ycombinator.com/item?id=30779913) that `rr` can now work on ARM64, we at Undo (https://undo.io) have an ARM64 port under routine internal testing as we expect it to be important in the future.
GDB's built-in record/replay is also supposed to work on ARM64 - https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and...
Last I heard, on x86, the performance and memory overheads of that implementation were quite high but if it solves your problem maybe that's fine!
https://docs.microsoft.com/en-us/windows-hardware/drivers/de...
Do not underestimate the power of the print command! And the advanced stuff like revers-debugging, multi-threading (all-stop mode - which is the default - and the non-stop mode), binary manipulation (yep, it is possible), and remote debugging. Nowadays accompanied by stuff like debuginfod. What still need to try is the TUI modes because I assume it will improve my personal experience once I find a way of using it.
I've ended up writing all stuff useful for me onto paper, later a markdown and I can recommend everyone doing similar. GDB's learning curve is not like VIM (which is either a wall or a rocket - both looking similar on paper) but it is going upwards.
Today's highlight is "Why do I've to set up all my breakpoints again? You need to save them like an IDE":
https://sourceware.org/gdb/onlinedocs/gdb/Save-Breakpoints.h...
> I've ended up writing all stuff useful for me onto paper, later a markdown
Would you like to share? :)It is powerful because it is ancient.
Still waiting for it to print the contents of a QList or QString, or pull actual data in cases where I see <optimized out>.
ModuleNotFoundError: No module named 'qt'
Changing KDevelop's gdbinit to `from .qt import register_qt_printers` results in: ImportError: attempted relative import with no known parent package
The problem is that sourcing KDevelop's gdbinit doesn't let Python import packages relative to that file. Is there an alternative way to do this?https://github.com/qbittorrent/qBittorrent/wiki/Setup-GDB-wi...
This will do the trick, so long as the compiler hasn't completely elided a value.
It feels like there's scope for the DWARF debug info to make optimised variables debuggable normally but that's probably a pretty hairy problem.
https://sourceware.org/gdb/onlinedocs/gdb/Command-History.ht...
Accidently I also moved my mouse cursor over a variable while stopped at a breakpoint, in a terminal, over ssh, and there is a hovering balloon popping up with the current state of that variable. Mind blown.
When I was studying reverse engineering though, I came across a really cool kit (which I've yet to find an alternative for lldb, which would be nice given: rust)
I'd recommend checking it out, if for no other reason than it makes a lot of things really obvious (like watching what value lives in which register).
LLDB's closest alternative to this is called Venom, but it's not the same at all. https://github.com/ovh/venom
The GDB Documentation is really nice (as GNU project docs tend to be) and I've made lots of use of them. The fact that they've also documented things like the serial comms protocol is a level further still.
Some related stuff we (Undo) have produced about GDB and might be interesting to the audience here...
Articles about less-known parts of GDB functionality: https://undo.io/resources/gdb-watchpoint/
Greg Law's quick talk on little-known features of GDB: https://undo.io/resources/cppcon-2015-greg-law-give-me-15-mi...
Greg's bigger talk on GDB: https://www.youtube.com/watch?v=-n9Fkq1e6sg
> To put it bluntly, debugging on Linux is just really bad. We believe it is the biggest roadblock to great software for that platform. Don't get us wrong - debugging on Windows isn't great either. But the standard Visual Studio debugger is still much better than anything on Linux.
> So we want to make Linux debugging as good as Windows debugging. And then we want to make both better - much better. There are so many better debugging tools that we can imagine having, and yet even today's best debuggers provide barely any functionality that wasn't in debuggers twenty years ago.
> Also, we think there's a lot of value in having one great debugger that you can use on every platform. RAD develops software for roughly 18 platforms now. A big part of the friction of a new platform is dealing with different toolsets.
> Compilers, linkers and runtimes are all hard to deal with, certainly, but you typically finish setting those up in a few days or weeks. The debuggers, on the other hand, are tools you have to use every day for as long as you develop on that platform!
I guess it's just really hard to do this stuff
For background, our dev environments consisted of Windows PCs which we used to ssh (using putty, exceed, etc) into a SPARC/Solaris machine to do all of our actual work. Our tools consisted of vi (not vim), clearcase, and whatever other command line tools were available (good luck asking for anything new to be installed).
At some point, I guess somebody installed GNU tools on the solaris machine because I managed to find gdb while rooting around... which I'd never used before - so I set about learning. It proved to be a huge help. I tried to show it to some of the other engineers, but few seemed interested.
Not fun, when I model my code / unit test against a working sample and some method 25+ layers down does not work as expected as it does not have expected input when the stack frame does not even give me the caller. Is there a better way than peppering the codebase with logging statements?
Every time a JITted object file is added using the API, the entire symbol table is sorted. If you have 10,000+ JITted object files as we do - it takes hours to days to weeks to register them all.
We use the Undo time traveling debugger that builds on top of GDB. It's awesome but we are crippled because of the JIT API implementation.
I'd love to see this get fixed - if anyone knows who to talk with about it - drop me a line.
Does VIM has anything similar?
There is also vimspector, which is more advanced, a full blown debugging solution, using LSP and its lesser known cousin, the debugger adapter protocol. However, its quite hard to set up and success isn't guaranteed.
It is noteable that nvim-dap just provides support for debug adapters, if you are looking for nice UI, there are other plugins such as nvim-dap-ui [2].
In vim land, there is vimspector. I have not used vimspector myself, but from what I hear, it is slower than nvim-dap.
[1] https://microsoft.github.io/debug-adapter-protocol/implement...
Most of IDEs have a similar capability to be able to use debug view without setting up a project.
https://github.com/cyrus-and/gdb-dashboard
There's also Voltron which works with both gdb and lldb (amongst others):
But if you really only need to watch variables any GUI frontend to gdb like QtCreator or DDD will do.
My subjective opinion is that C-Lion is just a little bit more solid/complete, but Microsoft are investing heavily in VScode. It's great to see some serious competition by two well-resourced players working on this stuff.
Personally I'm always happiest with GDB tui. It's all the standard arguments of command-line vs GUI. When you know what you're doing CLI (with tab-complete) is just a faster way to accomplish the task, but when you're a noobie or an infrequent user the GUI wins because it's so much more discoverable.
I'm curious if it can be an alternative to visual studio, meaning a window showing the stack, locals, watch, etc?
I'd expect Emacs to have some GDB integration as well.
https://www.gnu.org/software/emacs/manual/html_node/emacs/GD...
It gives you an IDE-like interface but supports easy access to the command line (as you'd expect, given Emacs's focus on text-based UX). Unlike (some of) the full IDEs it doesn't require you to be fully committed to a particular way of doing things (build systems, projects, etc).
I understand that VScode and CLion are also fairly lightweight IDEs and have GDB integration too, though ISTR VScode doesn't have watchpoint support yet. You can always type directly into the console, though.
Emacs has GDB integration too, but it has been a long time since I used Emacs. Again, I don't remember being very successful with it and went back to the command line.
Edit: By Visual Studio, I mean the real one, not VS Code. VS Code is on the same level as Sublime Text, maybe a little bit better integrated. Among the different environments I have used, I consider Visual Studio to have the best C/C++ debugger, by far.
All of these are capable of the basic single-threaded debug operations. Multithreaded is not as robust, but it's quite a cookie per se.
For the basics the TUI is very much alright, as long as you remember the hotkeys.
Are there other debuggers out there that are easier to extend ?
I've done some minimal poking about in the code; I found its object-orientation a bit hard to grok (just for me personally) but it seemed to be quite uniformly applied so it might well be easier to work with.
This is a PITA under Linux, I figured this out but nor happy I had to look.
I wish Linux was like OpenBSD, where you get core files by default. This give me yet another reason to switch to OpenBSD, I only wish some other issues I am having with OpenBSD could get solved.
I've previously configured `/proc/sys/kernel/core_pattern` to generate core dumps by default (and not pipe them to a core dump collection program, which may be useful for error reporting but is rarely what I want).
There's also `gcore` for doing on-demand core dumps.
I wish it were possible to configure core dump behaviour per-process (or something similar).
ulimit -S -c unlimited
sudo sysctl -w kernel.core_pattern=core
took me a while to figure this out, HTH
By this, are you referring to the behavior: "By default, this memory image is written to a file named programname.core in the working directory, provided the terminated process had write permission in the directory[...]" (from https://man.openbsd.org/core.5) ?
Also, do you know if there's a way to obtain a core file from a running process on OpenBSD? I don't see a port of gcore, and (e)gdb on OpenBSD doesn't support the generate-core-file command (it says, "Can't create a corefile").
kill -ABRT pid
should do it
However, I tried your suggestion from another terminal, and gdb appears to shield the program somehow. What ended up working is running "signal SIGABRT" from within gdb.
One thing that's still lacking is gcore's ability to take a snapshot of the core without killing the program. "Unlike after a crash, after gcore finishes its job the program remains running without any change." https://www.man7.org/linux/man-pages/man1/gcore.1.html
My code is for linear algebra stuff, so it is pretty much a straight shot through/filling in some RCI loop most of the time, I usually just have to find which OpenMP or MPI barrier is misbehaving.
It's like using Google Maps to see the general shape of a landscape. A debugger is generally more like Google Streetview - you get strictly more detail and it makes some problems way easier to solve. It's just not always the easiest way to get an overview.
With that in mind, though, GDB's "Dynamic Printf" is pretty cool: https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Printf.htm...
You basically configure GDB to add printfs to the program you're debugging, without having to rebuild it. You just run under GDB and the prints will run. As a bonus, you can also interact using normal debugging commands too.
> p myfunction()
> break my_file.c:123 if my_function() == 0x5
i.e. please stop at `my_file.c` line 123 but when `my_function()` is returning the value 0x5. GDB will handle calling the function and checking its value every time you get there.