GDB
is a general purpose, platform-independent debugger that
can be used to debug mixed-language programs compiled with gcc,
and in particular is capable of debugging Ada programs compiled with
GNAT. The latest versions of GDB
are Ada-aware and can handle
complex Ada data structures.
See Debugging with GDB,
for full details on the usage of GDB
, including a section on
its usage on programs. This manual should be consulted for full
details. The section that follows is a brief introduction to the
philosophy and use of GDB
.
When GNAT programs are compiled, the compiler optionally writes debugging information into the generated object file, including information on line numbers, and on declared types and variables. This information is separate from the generated code. It makes the object files considerably larger, but it does not add to the size of the actual executable that will be loaded into memory, and has no impact on run-time performance. The generation of debug information is triggered by the use of the -g switch in the gcc or gnatmake command used to carry out the compilations. It is important to emphasize that the use of these options does not change the generated code.
The debugging information is written in standard system formats that
are used by many tools, including debuggers and profilers. The format
of the information is typically designed to describe C types and
semantics, but GNAT implements a translation scheme which allows full
details about Ada types and variables to be encoded into these
standard C formats. Details of this encoding scheme may be found in
the file exp_dbug.ads in the GNAT source distribution. However, the
details of this encoding are, in general, of no interest to a user,
since GDB
automatically performs the necessary decoding.
When a program is bound and linked, the debugging information is collected from the object files, and stored in the executable image of the program. Again, this process significantly increases the size of the generated executable file, but it does not increase the size of the executable program itself. Furthermore, if this program is run in the normal manner, it runs exactly as if the debug information were not present, and takes no more actual memory.
However, if the program is run under control of GDB
, the
debugger is activated. The image of the program is loaded, at which
point it is ready to run. If a run command is given, then the program
will run exactly as it would have if GDB
were not present. This
is a crucial part of the GDB
design philosophy. GDB
is
entirely non-intrusive until a breakpoint is encountered. If no
breakpoint is ever hit, the program will run exactly as it would if no
debugger were present. When a breakpoint is hit, GDB
accesses
the debugging information and can respond to user commands to inspect
variables, and more generally to report on the state of execution.