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