utility

Team-FLY

A.4 Debugging Aids

This section discusses the lint utility, debuggers , the truss utility and profiling.

A.4.1 The lint utility

The lint utility finds errors and inconsistencies in C source files. The lint program performs type checking, tries to detect unreachable statements, and points out code that might be wasteful or nonportable; lint also detects a variety of common errors, such as using = instead of == or omitting & in arguments of scanf . You should call lint for all programs. Pay attention to the resulting warning messages, since lint is pickier than the C compiler in many areas. The C compiler presumes that programs have already been linted and is usually implemented to be fast rather than fussy.

Exercise A.22

Add the following lines to the description file of Example A.18 to lint the sources.

 lintall:            lint my.c mylib.c > my.lint 

Type make lintall to lint the programs. The output of lint is in my.lint .

Exercise A.23

How should the following lint message be interpreted?

 implicitly declared to return int:     (14) strtok 

Answer:

This lint message warns that the program did not include the string.h header file associated with strtok appearing on line 14 of the source file. Lacking information to the contrary, the compiler assumes that strtok returns int . Unfortunately, strtok returns char* . The lack of header can lead to disastrous results at execution time.

Exercise A.24

How should the following lint message be interpreted?

 (5) warning: variable may be used before set: p 

Answer:

This message usually appears when the program uses a pointer before setting its value, as in the following code segment.

 char *p; scanf("%s", p); 

The pointer p is not pointing to an appropriate character buffer. The code may compile, but the program will probably produce a segmentation error when executed.

A.4.2 Debuggers

Debuggers are runtime programs that monitor and control the execution of other programs. Common debuggers found in UNIX environments are dbx , adb , sdb and debug . Debuggers allow a user to single-step through a program and monitor changes to specified variables . To use a debugger, compile the program with the -g option.

Exercise A.25

Compile the program my.c with the -g option as follows to instrument the executable for debugger control.

 cc -g -o my my.c 

Run my under the dbx debugger by typing the following command.

 dbx my 

The debugger responds with the following prompt.

 (dbx) 

Respond with help for a list of commands or run to run the program. Set a stopping point with stop , or turn on tracing when a variable changes, by typing trace before typing run .

Many programmers, especially beginning programmers, find debuggers useful for pointer problems. Some debuggers have graphical user interfaces that make them easier to use. Standard debuggers are less useful in a concurrent environment, in which processes interact or timing can change the behavior of a program. Thread debuggers are also available on a limited basis. Debuggers may help you find a particular execution error, but using a debugger is no substitute for having a program test plan. Good error trapping for function calls is probably the most valuable debugging strategy to follow.

A.4.3 The truss utility

For runtime debugging, the truss command is useful if it is available. The truss command produces a trace of system calls that are made and the signals delivered while a particular process is running. Use the -f option with truss to trace the calls of all children of the process. The truss command is not part of POSIX and is not available on all systems.

Exercise A.26

Suppose that a program called dvips is installed on a system and that this program accesses the psfonts.map file. You have placed a copy of psfonts.map in the bin subdirectory of your home directory. When you run the program, you receive the following error message.

 unable to open file 

How can you figure out how to correct the problem?

Answer:

Try executing the following command (from a C shell).

 truss dvips -f t.dvi & grep psfonts.map 

The truss program runs the command dvips -f t.dvi , and grep displays the output lines containing psfonts.map . The & argument causes both the standard output and the standard error of truss to be piped to the standard input of grep . The output might appear as follows.

 open("./psfonts.map", O_RDONLY, 0666)         Err#2 ENOENT open("/usr/local/tex/dvips/psfonts.map", O_RDONLY, 0666) Err#2 ENOENT 

The output reports that the program first looked for psfonts.map in the current directory and then in the directory /usr/local/tex/dvips . Copy the psfonts.map to /usr/local/tex/dvips and everything should be ready to go!

A.4.4 Profilers

Most C compilers have options for profiling programs. Profilers accumulate statistical information such as execution times for basic blocks and frequency of calls. Consult the man pages for prof , gprof , monitor , profil and tcov as well as for cc to obtain additional information about profiling.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

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