Go to the first, previous, next, last section, table of contents.
This chapter describes some tips and tricks for debugging numerical programs which use GSL.
Any errors reported by the library are routed through the function
gsl_error
. By running your programs under gdb and setting a
breakpoint in this function you can automatically catch any library
errors. You can add a breakpoint for every session by putting
break gsl_error
into your `.gdbinit' file in the directory where your program is
started. If the breakpoint catches an error then you can use a backtrace
(bt
) to see the call-tree, and the arguments which possibly
caused the error. By moving into the caller (up
, up
) you
can investigate the values of variable at that point.
Here is an example from the program fft/test_trap
, which contains
the following line,
status = gsl_fft_complex_wavetable_alloc (0, &complex_wavetable);
The function gsl_fft_complex_wavetable_alloc
takes the length of
an FFT as its first argument. When this line is executed an error will
be generated because the length of an FFT is not allowed to be zero.
To debug this problem we start gdb
, using the file
`.gdbinit' to define a breakpoint in gsl_error
,
bash$ gdb test_trap GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.16 (i586-debian-linux), Copyright 1996 Free Software Foundation, Inc... Breakpoint 1 at 0x8050b1e: file error.c, line 14.
When we run the program this breakpoint catches the error and shows the reason for it.
(gdb) run Starting program: /home/bjg/gsl/fft/test_trap Breakpoint 1, gsl_error (reason=0x8052b0d "length n must be positive integer", file=0x8052b04 "c_init.c", line=108, gsl_errno=1) at error.c:14 14 if (gsl_error_handler)
The first argument of gsl_error
is always a string describing the
error. Now we can look at the backtrace to see what caused the problem,
(gdb) bt #0 gsl_error (reason=0x8052b0d "length n must be positive integer", file=0x8052b04 "c_init.c", line=108, gsl_errno=1) at error.c:14 #1 0x8049376 in gsl_fft_complex_wavetable_alloc (n=0, wavetable=0xbffff778) at c_init.c:108 #2 0x8048a00 in main (argc=1, argv=0xbffff9bc) at test_trap.c:94 #3 0x80488be in ___crt_dummy__ ()
We can see that the error was generated in the function
gsl_fft_complex_wavetable_alloc
when it was called with an
argument of n=0. The original call came from line 94 in the
file `test_trap.c'.
By moving up to the level of the original call we can find the line that caused the error,
(gdb) up #1 0x8049376 in gsl_fft_complex_wavetable_alloc (n=0, wavetable=0xbffff778) at c_init.c:108 108 GSL_ERROR ("length n must be positive integer", GSL_EDOM); (gdb) up #2 0x8048a00 in main (argc=1, argv=0xbffff9bc) at test_trap.c:94 94 status = gsl_fft_complex_wavetable_alloc (0, &complex_wavetable);
Thus we have found the line that caused the problem. From this point we
could also print out the values of other variables such as
complex_wavetable
.
Writing reliable numerical programs in C requires great care. The following GCC warning options are recommended when compiling numerical programs:
gcc -ansi -pedantic -Werror -Wall -W -Wmissing-prototypes -Wstrict-prototypes -Wtraditional -Wconversion -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Waggregate-return -fshort-enums -fno-common -Wnested-externs -Dinline= -g -O4
For details of each option consult the manual Using and porting GCC. The following table gives a brief explanation of what types of errors these warnings catch.
-ansi -pedantic
-Werror
-Wall
-Wall
, but it is not enough on its own.
-O4
-Wall
rely on the optimizer to analyze the code. If there is no
optimization then the warnings aren't generated.
-W
-Wall
, such as
missing return values and comparisons between signed and unsigned
integers.
-Wmissing-prototypes -Wstrict-prototypes
-Wtraditional
-Wconversion
unsigned int x = -1
. If you need
to perform such a conversion you can use an explicit cast.
-Wshadow
-Wpointer-arith -Wcast-qual -Wcast-align
void
, if you remove a const
cast from a pointer, or if you cast a pointer to a type which has a
different size, causing an invalid alignment.
-Wwrite-strings
const
qualifier so that it
will be a compile-time error to attempt to overwrite them.
-Waggregate-return
-fshort-enums
enum
as short as possible. Normally
this makes an enum
different from an int
. Consequently any
attempts to assign a pointer-to-int to a pointer-to-enum will generate a
cast-alignment warning.
-fno-common
extern
declaration.
-Wnested-externs
extern
declaration is encountered within an
function.
-Dinline=
inline
keyword is not part of ANSI C. Thus if you want to use
-ansi
with a program which uses inline functions you can use this
preprocessor definition to remove the inline
keywords.
-g
gdb
. The only effect of debugging symbols
is to increase the size of the file, and you can use the strip
command to remove them later if necessary.
Go to the first, previous, next, last section, table of contents.