Mostly notes for the Cppcon talk of Greg Law in 2023.
Basically, use the command record
and run the program. After crashing, you can then use reverse-* commands like reverse-stepi
(rsi
) to step backwards through the execution.
To hunt down an undeterminstic bug, Greg makes a program run repeatedly until it crashes, by executing the following sequence.
gdb <cmd>
. In gdb
b main
commands
(attach commands to breakpoint)
record
continue
end
(ends the attaching of commands)b _exit
commands
run
end
So, when main is called, recording starts. When _exit is called (i.e. normal termination), gdb restarts the program.
When the program crashed, the “time travel” records allow to inspect the execution before the crash.
The project GDB Dashboard provides a .gdbinit that provides an interesting TUI mode, when executed.
It can be explicitly executed: gdb -x path/to/gdb-dashboard/.gdbinit
Or put it in your home directory, to automatically load it.
Somewhat related: There is a built-in TUI mode, that can be toggled with Ctrl-x a
.
Unrelated to the mentioned Cppcon talk, I often want to get a stack trace when an exception was raised. Unfortunately when the exception triggered abort, the original stack trace can’t be accessed anymore.
catch throw [regexp]
stops the program when an exception matching the regexp is thrown. The regexp part hasn’t yet worked for me though. So the program is stopped at any exception.
Another solution is to set a breakpoint on *__cxa_throw*: b __cxa_throw