gdb: Checkpoint/Restart
4.12 Setting a _Bookmark_ to Return to Later
============================================
On certain operating systems(1), GDB is able to save a "snapshot" of a
program's state, called a "checkpoint", and come back to it later.
Returning to a checkpoint effectively undoes everything that has
happened in the program since the 'checkpoint' was saved. This includes
changes in memory, registers, and even (within some limits) system
state. Effectively, it is like going back in time to the moment when
the checkpoint was saved.
Thus, if you're stepping thru a program and you think you're getting
close to the point where things go wrong, you can save a checkpoint.
Then, if you accidentally go too far and miss the critical statement,
instead of having to restart your program from the beginning, you can
just go back to the checkpoint and start again from there.
This can be especially useful if it takes a lot of time or steps to
reach the point where you think the bug occurs.
To use the 'checkpoint'/'restart' method of debugging:
'checkpoint'
Save a snapshot of the debugged program's current execution state.
The 'checkpoint' command takes no arguments, but each checkpoint is
assigned a small integer id, similar to a breakpoint id.
'info checkpoints'
List the checkpoints that have been saved in the current debugging
session. For each checkpoint, the following information will be
listed:
'Checkpoint ID'
'Process ID'
'Code Address'
'Source line, or label'
'restart CHECKPOINT-ID'
Restore the program state that was saved as checkpoint number
CHECKPOINT-ID. All program variables, registers, stack frames etc.
will be returned to the values that they had when the checkpoint
was saved. In essence, gdb will "wind back the clock" to the point
in time when the checkpoint was saved.
Note that breakpoints, GDB variables, command history etc. are not
affected by restoring a checkpoint. In general, a checkpoint only
restores things that reside in the program being debugged, not in
the debugger.
'delete checkpoint CHECKPOINT-ID'
Delete the previously-saved checkpoint identified by CHECKPOINT-ID.
Returning to a previously saved checkpoint will restore the user
state of the program being debugged, plus a significant subset of the
system (OS) state, including file pointers. It won't "un-write" data
from a file, but it will rewind the file pointer to the previous
location, so that the previously written data can be overwritten. For
files opened in read mode, the pointer will also be restored so that the
previously read data can be read again.
Of course, characters that have been sent to a printer (or other
external device) cannot be "snatched back", and characters received from
eg. a serial device can be removed from internal program buffers, but
they cannot be "pushed back" into the serial pipeline, ready to be
received again. Similarly, the actual contents of files that have been
changed cannot be restored (at this time).
However, within those constraints, you actually can "rewind" your
program to a previously saved point in time, and begin debugging it
again -- and you can change the course of events so as to debug a
different execution path this time.
Finally, there is one bit of internal program state that will be
different when you return to a checkpoint -- the program's process id.
Each checkpoint will have a unique process id (or PID), and each will be
different from the program's original PID. If your program has saved a
local copy of its process id, this could potentially pose a problem.
4.12.1 A Non-obvious Benefit of Using Checkpoints
-------------------------------------------------
On some systems such as GNU/Linux, address space randomization is
performed on new processes for security reasons. This makes it
difficult or impossible to set a breakpoint, or watchpoint, on an
absolute address if you have to restart the program, since the absolute
location of a symbol will change from one execution to the next.
A checkpoint, however, is an _identical_ copy of a process.
Therefore if you create a checkpoint at (eg.) the start of main, and
simply return to that checkpoint instead of restarting the process, you
can avoid the effects of address randomization and your symbols will all
stay in the same place.
---------- Footnotes ----------
(1) Currently, only GNU/Linux.