diff options
Diffstat (limited to 'gsl-1.9/doc/debug.texi')
-rw-r--r-- | gsl-1.9/doc/debug.texi | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/gsl-1.9/doc/debug.texi b/gsl-1.9/doc/debug.texi new file mode 100644 index 0000000..2cf0065 --- /dev/null +++ b/gsl-1.9/doc/debug.texi @@ -0,0 +1,389 @@ +This chapter describes some tips and tricks for debugging numerical +programs which use GSL. + +@menu +* Using gdb:: +* Examining floating point registers:: +* Handling floating point exceptions:: +* GCC warning options for numerical programs:: +* Debugging References:: +@end menu + +@node Using gdb +@section Using gdb +@cindex gdb +@cindex debugging numerical programs +@cindex breakpoints +Any errors reported by the library are passed to the function +@code{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 + +@example +break gsl_error +@end example +@comment + +@noindent +into your @file{.gdbinit} file in the directory where your program is +started. + +If the breakpoint catches an error then you can use a backtrace +(@code{bt}) to see the call-tree, and the arguments which possibly +caused the error. By moving up into the calling function you can +investigate the values of variables at that point. Here is an example +from the program @code{fft/test_trap}, which contains the following +line, + +@smallexample +status = gsl_fft_complex_wavetable_alloc (0, &complex_wavetable); +@end smallexample + +@noindent +The function @code{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 @code{gdb}, using the file +@file{.gdbinit} to define a breakpoint in @code{gsl_error}, + +@smallexample +$ 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. +@end smallexample + +@noindent +When we run the program this breakpoint catches the error and shows the +reason for it. + +@smallexample +(gdb) run +Starting program: 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) +@end smallexample +@comment + +@noindent +The first argument of @code{gsl_error} is always a string describing the +error. Now we can look at the backtrace to see what caused the problem, + +@smallexample +(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__ () +@end smallexample +@comment + +@noindent +We can see that the error was generated in the function +@code{gsl_fft_complex_wavetable_alloc} when it was called with an +argument of @var{n=0}. The original call came from line 94 in the +file @file{test_trap.c}. + +By moving up to the level of the original call we can find the line that +caused the error, + +@smallexample +(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); +@end smallexample +@comment + +@noindent +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 +@code{complex_wavetable}. + +@node Examining floating point registers +@section Examining floating point registers + +The contents of floating point registers can be examined using the +command @code{info float} (on supported platforms). + +@smallexample +(gdb) info float + st0: 0xc4018b895aa17a945000 Valid Normal -7.838871e+308 + st1: 0x3ff9ea3f50e4d7275000 Valid Normal 0.0285946 + st2: 0x3fe790c64ce27dad4800 Valid Normal 6.7415931e-08 + st3: 0x3ffaa3ef0df6607d7800 Spec Normal 0.0400229 + st4: 0x3c028000000000000000 Valid Normal 4.4501477e-308 + st5: 0x3ffef5412c22219d9000 Zero Normal 0.9580257 + st6: 0x3fff8000000000000000 Valid Normal 1 + st7: 0xc4028b65a1f6d243c800 Valid Normal -1.566206e+309 + fctrl: 0x0272 53 bit; NEAR; mask DENOR UNDER LOS; + fstat: 0xb9ba flags 0001; top 7; excep DENOR OVERF UNDER LOS + ftag: 0x3fff + fip: 0x08048b5c + fcs: 0x051a0023 + fopoff: 0x08086820 + fopsel: 0x002b +@end smallexample + +@noindent +Individual registers can be examined using the variables @var{$reg}, +where @var{reg} is the register name. + +@smallexample +(gdb) p $st1 +$1 = 0.02859464454261210347719 +@end smallexample + +@node Handling floating point exceptions +@section Handling floating point exceptions + +It is possible to stop the program whenever a @code{SIGFPE} floating +point exception occurs. This can be useful for finding the cause of an +unexpected infinity or @code{NaN}. The current handler settings can be +shown with the command @code{info signal SIGFPE}. + +@smallexample +(gdb) info signal SIGFPE +Signal Stop Print Pass to program Description +SIGFPE Yes Yes Yes Arithmetic exception +@end smallexample + +@noindent +Unless the program uses a signal handler the default setting should be +changed so that SIGFPE is not passed to the program, as this would cause +it to exit. The command @code{handle SIGFPE stop nopass} prevents this. + +@smallexample +(gdb) handle SIGFPE stop nopass +Signal Stop Print Pass to program Description +SIGFPE Yes Yes No Arithmetic exception +@end smallexample + +@noindent +Depending on the platform it may be necessary to instruct the kernel to +generate signals for floating point exceptions. For programs using GSL +this can be achieved using the @code{GSL_IEEE_MODE} environment variable +in conjunction with the function @code{gsl_ieee_env_setup} as described +in @pxref{IEEE floating-point arithmetic}. + +@example +(gdb) set env GSL_IEEE_MODE=double-precision +@end example + + +@node GCC warning options for numerical programs +@section GCC warning options for numerical programs +@cindex warning options +@cindex gcc warning options + +Writing reliable numerical programs in C requires great care. The +following GCC warning options are recommended when compiling numerical +programs: + +@comment Uninitialized variables, conversions to and from integers or from +@comment signed to unsigned integers can all cause hard-to-find problems. For +@comment many non-numerical programs compiling with @code{gcc}'s warning option +@comment @code{-Wall} provides a good check against common errors. However, for +@comment numerical programs @code{-Wall} is not enough. + +@comment If you are unconvinced take a look at this program which contains an +@comment error that can occur in numerical code, + +@comment @example +@comment #include <math.h> +@comment #include <stdio.h> + +@comment double f (int x); + +@comment int main () +@comment @{ +@comment double a = 1.5; +@comment double y = f(a); +@comment printf("a = %g, sqrt(a) = %g\n", a, y); +@comment return 0; +@comment @} + +@comment double f(x) @{ +@comment return sqrt(x); +@comment @} +@comment @end example + +@comment @noindent +@comment This code compiles cleanly with @code{-Wall} but produces some strange +@comment output, + +@comment @example +@comment bash$ gcc -Wall tmp.c -lm +@comment bash$ ./a.out +@comment a = 1.5, sqrt(a) = 1 +@comment @end example + +@comment @noindent +@comment Note that adding @code{-ansi} does not help here, since the program does +@comment not contain any invalid constructs. What is happening is that the +@comment prototype for the function @code{f(int x)} is not consistent with the +@comment function call @code{f(y)}, where @code{y} is a floating point +@comment number. This results in the argument being silently converted to an +@comment integer. This is valid C, but in a numerical program it also likely to +@comment be a programming error so we would like to be warned about it. (If we +@comment genuinely wanted to convert @code{y} to an integer then we could use an +@comment explicit cast, @code{(int)y}). + +@comment Fortunately GCC provides many additional warnings which can alert you to +@comment problems such as this. You just have to remember to use them. Here is a +@comment set of recommended warning options for numerical programs. + +@example +gcc -ansi -pedantic -Werror -Wall -W + -Wmissing-prototypes -Wstrict-prototypes + -Wtraditional -Wconversion -Wshadow + -Wpointer-arith -Wcast-qual -Wcast-align + -Wwrite-strings -Wnested-externs + -fshort-enums -fno-common -Dinline= -g -O2 +@end example + +@noindent +For details of each option consult the manual @cite{Using and Porting +GCC}. The following table gives a brief explanation of what types of +errors these options catch. + +@table @code +@item -ansi -pedantic +Use ANSI C, and reject any non-ANSI extensions. These flags help in +writing portable programs that will compile on other systems. +@item -Werror +Consider warnings to be errors, so that compilation stops. This prevents +warnings from scrolling off the top of the screen and being lost. You +won't be able to compile the program until it is completely +warning-free. +@item -Wall +This turns on a set of warnings for common programming problems. You +need @code{-Wall}, but it is not enough on its own. +@item -O2 +Turn on optimization. The warnings for uninitialized variables in +@code{-Wall} rely on the optimizer to analyze the code. If there is no +optimization then these warnings aren't generated. +@item -W +This turns on some extra warnings not included in @code{-Wall}, such as +missing return values and comparisons between signed and unsigned +integers. +@item -Wmissing-prototypes -Wstrict-prototypes +Warn if there are any missing or inconsistent prototypes. Without +prototypes it is harder to detect problems with incorrect arguments. +@item -Wtraditional +This warns about certain constructs that behave differently in +traditional and ANSI C. Whether the traditional or ANSI interpretation +is used might be unpredictable on other compilers. +@item -Wconversion +The main use of this option is to warn about conversions from signed to +unsigned integers. For example, @code{unsigned int x = -1}. If you need +to perform such a conversion you can use an explicit cast. +@item -Wshadow +This warns whenever a local variable shadows another local variable. If +two variables have the same name then it is a potential source of +confusion. +@item -Wpointer-arith -Wcast-qual -Wcast-align +These options warn if you try to do pointer arithmetic for types which +don't have a size, such as @code{void}, if you remove a @code{const} +cast from a pointer, or if you cast a pointer to a type which has a +different size, causing an invalid alignment. +@item -Wwrite-strings +This option gives string constants a @code{const} qualifier so that it +will be a compile-time error to attempt to overwrite them. +@item -fshort-enums +This option makes the type of @code{enum} as short as possible. Normally +this makes an @code{enum} different from an @code{int}. Consequently any +attempts to assign a pointer-to-int to a pointer-to-enum will generate a +cast-alignment warning. +@item -fno-common +This option prevents global variables being simultaneously defined in +different object files (you get an error at link time). Such a variable +should be defined in one file and referred to in other files with an +@code{extern} declaration. +@item -Wnested-externs +This warns if an @code{extern} declaration is encountered within a +function. +@item -Dinline= +The @code{inline} keyword is not part of ANSI C. Thus if you want to use +@code{-ansi} with a program which uses inline functions you can use this +preprocessor definition to remove the @code{inline} keywords. +@item -g +It always makes sense to put debugging symbols in the executable so that +you can debug it using @code{gdb}. The only effect of debugging symbols +is to increase the size of the file, and you can use the @code{strip} +command to remove them later if necessary. +@end table + +@comment For comparison, this is what happens when the test program above is +@comment compiled with these options. + +@comment @example +@comment bash$ gcc -ansi -pedantic -Werror -W -Wall -Wtraditional +@comment -Wconversion -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align +@comment -Wwrite-strings -Waggregate-return -Wstrict-prototypes -fshort-enums +@comment -fno-common -Wmissing-prototypes -Wnested-externs -Dinline= +@comment -g -O4 tmp.c +@comment cc1: warnings being treated as errors +@comment tmp.c:7: warning: function declaration isn't a prototype +@comment tmp.c: In function `main': +@comment tmp.c:9: warning: passing arg 1 of `f' as integer rather than floating +@comment due to prototype +@comment tmp.c: In function `f': +@comment tmp.c:14: warning: type of `x' defaults to `int' +@comment tmp.c:15: warning: passing arg 1 of `sqrt' as floating rather than integer +@comment due to prototype +@comment make: *** [tmp] Error 1 +@comment @end example + +@comment @noindent +@comment The error in the prototype is flagged, plus the fact that we should have +@comment defined main as @code{int main (void)} in ANSI C. Clearly there is some +@comment work to do before this program is ready to run. + +@node Debugging References +@section References and Further Reading + +The following books are essential reading for anyone writing and +debugging numerical programs with @sc{gcc} and @sc{gdb}. + +@itemize @asis +@item +R.M. Stallman, @cite{Using and Porting GNU CC}, Free Software +Foundation, ISBN 1882114388 + +@item +R.M. Stallman, R.H. Pesch, @cite{Debugging with GDB: The GNU +Source-Level Debugger}, Free Software Foundation, ISBN 1882114779 +@end itemize + +@noindent +For a tutorial introduction to the GNU C Compiler and related programs, +see + +@itemize @asis +@item +B.J. Gough, @cite{An Introduction to GCC}, Network Theory Ltd, ISBN +0954161793 +@end itemize + + |