Книга: Fedora™ Unleashed, 2008 edition
Debugging Tools
Разделы на этой странице:
Debugging Tools
Debugging is both a science and an art. Sometimes, the simplest tool — the code listing — is the best debugging tool. At other times, however, you need to use other debugging tools. Three of these tools are splint
, gprof
, and gdb
.
Using splint
to Check Source Code
The splint
command is similar to the traditional Unix lint command: It statically examines source code for possible problems, and it also has many additional features. Even if your C code meets the standards for C and compiles cleanly, it might still contain errors. splint
performs many types of checks and can provide extensive error information. For example, this simple program might compile cleanly and even run:
$ gcc -o tux tux.c
$ ./tux
But the splint
command might point out some serious problems with the source:
$ splint tux.c
Splint 3.1.1 --- 17 Feb 2004 tux.c: (in function main)
tux.c:2:19: Return value (type int) ignored: putchar(t[++j] -...
Result returned by function call is not used. If this is intended, can cast
result to (void) to eliminate message. (Use -retvalint to inhibit warning)
Finished checking --- 1 code warning
You can use the splint
command's -strict
option, like this, to get a more verbose report:
$ splint -strict tux.c
GCC also supports diagnostics through the use of extensive warnings (through the -Wall
and -pedantic
options):
$ gcc -Wall tux.c
tux.c:1: warning: return type defaults to `int'
tux.c: In function `main':
tux.c:2: warning: implicit declaration of function `putchar'
Using gprof
to Track Function Time
You use the gprof
(profile) command to study how a program is spending its time. If a program is compiled and linked with -p
as a flag, a mon.out
file is created when it executes, with data on how often each function is called and how much time is spent in each function. gprof
parses and displays this data. An analysis of the output generated by gprof
helps you determine where performance bottlenecks occur. Using an optimizing compiler can speed up a program, but taking the time to use gprof
's analysis and revising bottleneck functions significantly improves program performance.
Doing Symbolic Debugging with gdb
The gdb
tool is a symbolic debugger. When a program is compiled with the -g
flag, the symbol tables are retained and a symbolic debugger can be used to track program bugs. The basic technique is to invoke gdb
after a core dump (a file containing a snapshot of the memory used by a program that has crashed) and get a stack trace. The stack trace indicates the source line where the core dump occurred and the functions that were called to reach that line. Often, this is enough to identify a problem. It isn't the limit of gdb
, though.
gdb
also provides an environment for debugging programs interactively. Invoking gdb
with a program enables you to set breakpoints, examine the values of variables, and monitor variables. If you suspect a problem near a line of code, you can set a breakpoint at that line and run gdb. When the line is reached, execution is interrupted. You can check variable values, examine the stack trace, and observe the program's environment. You can single-step through the program to check values. You can resume execution at any point. By using breakpoints, you can discover many bugs in code.
A graphical X Window System interface to gdb
is called the Data Display Debugger, or ddd
.