2006-01-04 Michael Snyder <msnyder@redhat.com>
* gdb.texinfo: Add documentation for linux-fork. * gdbint.texinfo: Add internal documentation for checkpoints.
This commit is contained in:
parent
099ac3dd7c
commit
5c95884b4c
|
@ -1,3 +1,8 @@
|
|||
2006-01-04 Michael Snyder <msnyder@redhat.com>
|
||||
|
||||
* gdb.texinfo: Add documentation for linux-fork.
|
||||
* gdbint.texinfo: Add internal documentation for checkpoints.
|
||||
|
||||
2006-01-02 Paul N. Hilfinger <hilfinger@gnat.com>
|
||||
|
||||
* gdb.texinfo (Omissions from Ada): Document that there is now
|
||||
|
|
|
@ -1740,6 +1740,7 @@ kill a child process.
|
|||
|
||||
* Threads:: Debugging programs with multiple threads
|
||||
* Processes:: Debugging programs with multiple processes
|
||||
* Checkpoint/Restart:: Setting a @emph{bookmark} to return to later
|
||||
@end menu
|
||||
|
||||
@node Compilation
|
||||
|
@ -2507,6 +2508,76 @@ unimpeded.
|
|||
Display the current debugger response to a @code{fork} or @code{vfork} call.
|
||||
@end table
|
||||
|
||||
@cindex debugging multiple processes
|
||||
On Linux, if you want to debug both the parent and child processes, use the
|
||||
command @w{@code{set detach-on-fork}}.
|
||||
|
||||
@table @code
|
||||
@kindex set detach-on-fork
|
||||
@item set detach-on-fork @var{mode}
|
||||
Tells gdb whether to detach one of the processes after a fork, or
|
||||
retain debugger control over them both.
|
||||
|
||||
@table @code
|
||||
@item on
|
||||
The child process (or parent process, depending on the value of
|
||||
@code{follow-fork-mode}) will be detached and allowed to run
|
||||
independently. This is the default.
|
||||
|
||||
@item off
|
||||
Both processes will be held under the control of @value{GDBN}.
|
||||
One process (child or parent, depending on the value of
|
||||
@code{follow-fork-mode}) is debugged as usual, while the other
|
||||
is held suspended.
|
||||
|
||||
@end table
|
||||
|
||||
@kindex show detach-on-follow
|
||||
@item show detach-on-follow
|
||||
Show whether detach-on-follow mode is on/off.
|
||||
@end table
|
||||
|
||||
If you choose to set @var{detach-on-follow} mode off, then
|
||||
@value{GDBN} will retain control of all forked processes (including
|
||||
nested forks). You can list the forked processes under the control of
|
||||
@value{GDBN} by using the @w{@code{info forks}} command, and switch
|
||||
from one fork to another by using the @w{@code{fork}} command.
|
||||
|
||||
@table @code
|
||||
@kindex info forks
|
||||
@item info forks
|
||||
Print a list of all forked processes under the control of @value{GDBN}.
|
||||
The listing will include a fork id, a process id, and the current
|
||||
position (program counter) of the process.
|
||||
|
||||
|
||||
@kindex fork @var{fork-id}
|
||||
@item fork @var{fork-id}
|
||||
Make fork number @var{fork-id} the current process. The argument
|
||||
@var{fork-id} is the internal fork number assigned by @value{GDBN},
|
||||
as shown in the first field of the @samp{info forks} display.
|
||||
|
||||
@end table
|
||||
|
||||
To quit debugging one of the forked processes, you can either detach
|
||||
from it by using the @w{@code{detach-fork}} command (allowing it to
|
||||
run independently), or delete (and kill) it using the
|
||||
@w{@code{delete-fork}} command.
|
||||
|
||||
@table @code
|
||||
@kindex detach-fork @var{fork-id}
|
||||
@item detach-fork @var{fork-id}
|
||||
Detach from the process identified by @value{GDBN} fork number
|
||||
@var{fork-id}, and remove it from the fork list. The process will be
|
||||
allowed to run independently.
|
||||
|
||||
@kindex delete-fork @var{fork-id}
|
||||
@item delete-fork @var{fork-id}
|
||||
Kill the process identified by @value{GDBN} fork number @var{fork-id},
|
||||
and remove it from the fork list.
|
||||
|
||||
@end table
|
||||
|
||||
If you ask to debug a child process and a @code{vfork} is followed by an
|
||||
@code{exec}, @value{GDBN} executes the new target up to the first
|
||||
breakpoint in the new target. If you have a breakpoint set on
|
||||
|
@ -2525,6 +2596,120 @@ You can use the @code{catch} command to make @value{GDBN} stop whenever
|
|||
a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set
|
||||
Catchpoints, ,Setting catchpoints}.
|
||||
|
||||
@node Checkpoint/Restart
|
||||
@section Setting a @emph{bookmark} to return to later
|
||||
|
||||
@cindex checkpoint
|
||||
@cindex restart
|
||||
@cindex bookmark
|
||||
@cindex snapshot of a process
|
||||
@cindex rewind program state
|
||||
|
||||
On certain operating systems@footnote{Currently, only
|
||||
@sc{gnu}/Linux.}, @value{GDBN} is able to save a @dfn{snapshot} of a
|
||||
program's state, called a @dfn{checkpoint}, and come back to it
|
||||
later.
|
||||
|
||||
Returning to a checkpoint effectively undoes everything that has
|
||||
happened in the program since the @code{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 @code{checkpoint}/@code{restart} method of debugging:
|
||||
|
||||
@table @code
|
||||
@kindex checkpoint
|
||||
@item checkpoint
|
||||
Save a snapshot of the debugged program's current execution state.
|
||||
The @code{checkpoint} command takes no arguments, but each checkpoint
|
||||
is assigned a small integer id, similar to a breakpoint id.
|
||||
|
||||
@kindex info checkpoints
|
||||
@item info checkpoints
|
||||
List the checkpoints that have been saved in the current debugging
|
||||
session. For each checkpoint, the following information will be
|
||||
listed:
|
||||
|
||||
@table @code
|
||||
@item Checkpoint ID
|
||||
@item Process ID
|
||||
@item Code Address
|
||||
@item Source line, or label
|
||||
@end table
|
||||
|
||||
@kindex restart @var{checkpoint-id}
|
||||
@item restart @var{checkpoint-id}
|
||||
Restore the program state that was saved as checkpoint number
|
||||
@var{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, @value{GDBN} 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.
|
||||
|
||||
@kindex delete-checkpoint @var{checkpoint-id}
|
||||
@item delete-checkpoint @var{checkpoint-id}
|
||||
Delete the previously-saved checkpoint identified by @var{checkpoint-id}.
|
||||
|
||||
@end table
|
||||
|
||||
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.
|
||||
|
||||
@cindex checkpoints and process id
|
||||
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 @var{pid}),
|
||||
and each will be different from the program's original @var{pid}.
|
||||
If your program has saved a local copy of its process id, this could
|
||||
potentially pose a problem.
|
||||
|
||||
@subsection A non-obvious benefit of using checkpoints
|
||||
|
||||
On some systems such as @sc{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 @emph{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.
|
||||
|
||||
@node Stopping
|
||||
@chapter Stopping and Continuing
|
||||
|
||||
|
|
|
@ -712,6 +712,38 @@ watchpoints might interfere with the underlying OS and are probably
|
|||
unavailable in many platforms.
|
||||
@end enumerate
|
||||
|
||||
@section Checkpoints
|
||||
@cindex checkpoints
|
||||
@cindex restart
|
||||
In the abstract, a checkpoint is a point in the execution history of
|
||||
the program, which the user may wish to return to at some later time.
|
||||
|
||||
Internally, a checkpoint is a saved copy of the program state, including
|
||||
whatever information is required in order to restore the program to that
|
||||
state at a later time. This can be expected to include the state of
|
||||
registers and memory, and may include external state such as the state
|
||||
of open files and devices.
|
||||
|
||||
There are a number of ways in which checkpoints may be implemented
|
||||
in gdb, eg. as corefiles, as forked processes, and as some opaque
|
||||
method implemented on the target side.
|
||||
|
||||
A corefile can be used to save an image of target memory and register
|
||||
state, which can in principle be restored later --- but corefiles do
|
||||
not typically include information about external entities such as
|
||||
open files. Currently this method is not implemented in gdb.
|
||||
|
||||
A forked process can save the state of user memory and registers,
|
||||
as well as some subset of external (kernel) state. This method
|
||||
is used to implement checkpoints on Linux, and in principle might
|
||||
be used on other systems.
|
||||
|
||||
Some targets, eg.@: simulators, might have their own built-in
|
||||
method for saving checkpoints, and gdb might be able to take
|
||||
advantage of that capability without necessarily knowing any
|
||||
details of how it is done.
|
||||
|
||||
|
||||
@section Observing changes in @value{GDBN} internals
|
||||
@cindex observer pattern interface
|
||||
@cindex notifications about changes in internals
|
||||
|
|
Loading…
Reference in New Issue