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.