17.1. Conceptual Overview

 < Day Day Up > 

A debugger is a program that lets you run a second program, which we will call the debuggee. The debugger lets you examine and change the state of the debuggee, and control its execution. In particular, you can single-step the program, executing one statement or instruction at a time, in order to watch the program's behavior.

Debuggers come in two flavors: instruction-level debuggers , which work at the level of machine instructions, and source-level debuggers , which operate in terms of your program's source code and programming language. The latter are considerably easier to use, and usually can do machine-level debugging if necessary. GDB is a source level debugger; it is probably the most widely applicable debugger (portable to the largest number of architectures) of any current debugger.

GDB itself provides two user interfaces : the traditional command-line interface (CLI) and a text user interface (TUI). The latter is meant for regular terminals or terminal emulators, dividing the screen into separate "windows" for the display of source code, register values, and so on.

GDB provides support for debugging programs written in C, C++, Objective C, Java,[*] and Fortran. It provides partial support for Modula-2 programs compiled with the GNU Modula-2 compiler and for Ada programs compiled with the GNU Ada Translator, GNAT. GDB provides some minimal support for debugging Pascal programs. The Chill language is no longer supported.

[*] GDB can only debug Java programs that have been compiled to native machine code with GJC, the GNU Java compiler (part of GCC, the GNU Compiler Collection).

When working with C++ and Objective C, GDB provides name demangling . C++ and Objective C encode overloaded procedure names into a unique "mangled" name that represents the procedure's return type, argument types, and class membership. This ensures so-called type-safe linkage . There are different methods for name mangling, thus GDB allows you to select among a set of supported methods, besides just automatically demangling names in displays.

If your program is compiled with GCC (the GNU Compiler Collection), using the -g3 and -gdwarf-2 options, GDB understands references to C preprocessor macros . This is particularly helpful for code using macros to simplify complicated struct and union members. GDB itself also has partial support for expanding preprocessor macros, with more support planned.

GDB allows you to specify several different kinds of files when doing debugging:

  • The exec file is the executable program to be debugged i.e., your program.

  • The optional core file is a memory dump generated by the program when it dies; this is used, together with the exec file, for post-mortem debugging. Core files are usually named core on commercial Unix systems. On BSD systems, they are named program.core. On GNU/Linux systems, they are named core.PID, where PID represents the process ID number. This lets you keep multiple core dumps, if necessary.

  • The symbol file is a separate file from which GDB can read symbol information: information describing variable names, types, sizes, and locations in the executable file. GDB, not the compiler, creates these files if necessary. Symbol files are rather esoteric; they're not necessary for run-of-the-mill debugging.

There are different ways to stop your program:

  • A breakpoint specifies that execution should stop at a particular source code location.

  • A watchpoint indicates that execution should stop when a particular memory location changes value. The location can be specified either as a regular variable name or via an expression (such as one involving pointers). If hardware assistance for watchpoints is available, GDB uses it, making the cost of using watchpoints small. If it is not available, GDB uses virtual memory techniques, if possible, to implement watchpoints. This also keeps the cost down. Otherwise, GDB implements watchpoints in software by single-stepping the program (executing one instruction at a time).

  • A catchpoint specifies that execution should stop when a particular event occurs.

The GDB documentation and command set often use the word breakpoint as a generic term to mean all three kinds of program stoppers . In particular, you use the same commands to enable, disable, and remove all three.

GDB applies different statuses to breakpoints (and watchpoints and catchpoints ). They may be enabled, which means that the program stops when the breakpoint is hit (or fires), disabled, which means that GDB keeps track of them but that they don't affect execution, or deleted, which means that GDB forgets about them completely. As a special case, breakpoints can be enabled only once. Such a breakpoint stops execution when it is encountered, then becomes disabled (but not forgotten).

Breakpoints may have conditions associated with them. When execution reaches the breakpoint, GDB checks the condition, stopping the program only if the condition is true.

Breakpoints may also have an ignore count, which is a count of how many times GDB should ignore the breakpoint when it's reached. As long as a breakpoint's ignore count is nonzero, GDB does not bother checking any condition associated with the breakpoint.

Perhaps the most fundamental concept for working with GDB is that of the frame. This is short for stack frame, a term from the compiler field. A stack frame is the collection of information needed for each separate function invocation. It contains the function's parameters and local variables, as well as linkage information indicating where return values should be placed and the location the function should return to. GDB assigns numbers to frames, starting at 0 and going up. Frame 0 is the innermost frame, i.e., the function most recently called.

GDB uses the readline library, as does the Bash shell, to provide command history, command completion, and interactive editing of the command line. Both Emacs and vi style editing commands are available.

Finally, GDB has many features of a programming language. You can define your own variables and apply common programming language operators to them. You can also define your own commands. Additionally, you can define special hook commands, user-defined commands that GDB executes before or after running a built-in command. (See the entry for define in the section "Alphabetical Summary of GDB Commands" for the details.) You can also create while loops and test conditions with if ... else ... end.

GDB is typically used to debug programs on the same machine (host) on which it's running. GDB can also be configured for cross-debugging, i.e., controlling a remote debuggee with a possibly different machine architecture (the target). Remote targets are usually connected to the host via a serial port or a network connection. Such use is rather esoteric and is therefore not covered here. See the GDB documentation for the full details.

17.1.1. Source Code Locations

GDB is the default debugger on GNU/Linux and BSD systems. It is usable on just about any modern Unix system, though, as well as many older ones. (However, if your system is really ancient, you may need to fall back to an older version of GDB.) Besides the command line and text user interfaces built in to GDB, there are other programs that provide GUI debuggers. Two of the more popular ones are ddd (the Data Display Debugger) and Insight . Both of these use GDB to provide the underlying debugging functionality. Source code URLs for these programs are listed in the following table.

Debugger

Location

ddd

ftp://ftp.gnu.org/gnu/ddd/

GDB

ftp://ftp.gnu.org/gnu/gdb/

Insight

http://sources.redhat.com/insight/


     < Day Day Up > 


    Unix in a Nutshell
    Unix in a Nutshell, Fourth Edition
    ISBN: 0596100299
    EAN: 2147483647
    Year: 2005
    Pages: 201

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net