~ubuntu-branches/ubuntu/dapper/gsl-ref-html/dapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.54+ (gsl)
     from /home/bjg/gsl.redhat/doc/gsl-ref.texi on 14 September 2005 -->

<TITLE>GNU Scientific Library -- Reference Manual - Debugging Numerical Programs</TITLE>
<link href="gsl-ref_41.html" rel=Next>
<link href="gsl-ref_39.html" rel=Previous>
<link href="gsl-ref_toc.html" rel=ToC>

</HEAD>
<BODY>
<p>Go to the <A HREF="gsl-ref_1.html">first</A>, <A HREF="gsl-ref_39.html">previous</A>, <A HREF="gsl-ref_41.html">next</A>, <A HREF="gsl-ref_50.html">last</A> section, <A HREF="gsl-ref_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC517" HREF="gsl-ref_toc.html#TOC517">Debugging Numerical Programs</A></H1>
<P>
This chapter describes some tips and tricks for debugging numerical
programs which use GSL.

</P>



<H2><A NAME="SEC518" HREF="gsl-ref_toc.html#TOC518">Using gdb</A></H2>
<P>
<A NAME="IDX2337"></A>
<A NAME="IDX2338"></A>
<A NAME="IDX2339"></A>
Any errors reported by the library are passed to the function
<CODE>gsl_error</CODE>.  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

</P>

<PRE>
break gsl_error
</PRE>

<P>
into your <TT>`.gdbinit'</TT> file in the directory where your program is
started.  

</P>
<P>
If the breakpoint catches an error then you can use a backtrace
(<CODE>bt</CODE>) 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</CODE>, which contains the following
line,

</P>

<PRE>
status = gsl_fft_complex_wavetable_alloc (0, &#38;complex_wavetable);
</PRE>

<P>
The function <CODE>gsl_fft_complex_wavetable_alloc</CODE> 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.

</P>
<P>
To debug this problem we start <CODE>gdb</CODE>, using the file
<TT>`.gdbinit'</TT> to define a breakpoint in <CODE>gsl_error</CODE>,

</P>

<PRE>
$ 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.
</PRE>

<P>
When we run the program this breakpoint catches the error and shows the
reason for it. 

</P>

<PRE>
(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) 
</PRE>

<P>
The first argument of <CODE>gsl_error</CODE> is always a string describing the
error.  Now we can look at the backtrace to see what caused the problem,

</P>

<PRE>
(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__ ()
</PRE>

<P>
We can see that the error was generated in the function
<CODE>gsl_fft_complex_wavetable_alloc</CODE> when it was called with an
argument of <VAR>n=0</VAR>.  The original call came from line 94 in the
file <TT>`test_trap.c'</TT>.

</P>
<P>
By moving up to the level of the original call we can find the line that
caused the error,

</P>

<PRE>
(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,
        &#38;complex_wavetable);
</PRE>

<P>
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</CODE>.

</P>


<H2><A NAME="SEC519" HREF="gsl-ref_toc.html#TOC519">Examining floating point registers</A></H2>

<P>
The contents of floating point registers can be examined using the
command <CODE>info float</CODE> (on supported platforms).

</P>

<PRE>
(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
</PRE>

<P>
Individual registers can be examined using the variables <VAR>$reg</VAR>,
where <VAR>reg</VAR> is the register name.

</P>

<PRE>
(gdb) p $st1 
$1 = 0.02859464454261210347719
</PRE>



<H2><A NAME="SEC520" HREF="gsl-ref_toc.html#TOC520">Handling floating point exceptions</A></H2>

<P>
It is possible to stop the program whenever a <CODE>SIGFPE</CODE> floating
point exception occurs.  This can be useful for finding the cause of an
unexpected infinity or <CODE>NaN</CODE>.  The current handler settings can be
shown with the command <CODE>info signal SIGFPE</CODE>.

</P>

<PRE>
(gdb) info signal SIGFPE
Signal  Stop  Print  Pass to program Description
SIGFPE  Yes   Yes    Yes             Arithmetic exception
</PRE>

<P>
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</CODE> prevents this.

</P>

<PRE>
(gdb) handle SIGFPE stop nopass
Signal  Stop  Print  Pass to program Description
SIGFPE  Yes   Yes    No              Arithmetic exception
</PRE>

<P>
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</CODE> environment variable
in conjunction with the function <CODE>gsl_ieee_env_setup()</CODE> as described
in see section <A HREF="gsl-ref_39.html#SEC513">IEEE floating-point arithmetic</A>.

</P>

<PRE>
(gdb) set env GSL_IEEE_MODE=double-precision
</PRE>



<H2><A NAME="SEC521" HREF="gsl-ref_toc.html#TOC521">GCC warning options for numerical programs</A></H2>
<P>
<A NAME="IDX2340"></A>
<A NAME="IDX2341"></A>

</P>
<P>
Writing reliable numerical programs in C requires great care.  The
following GCC warning options are recommended when compiling numerical
programs:

</P>


<PRE>
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 -O4
</PRE>

<P>
For details of each option consult the manual <CITE>Using and Porting
GCC</CITE>.  The following table gives a brief explanation of what types of
errors these options catch.

</P>
<DL COMPACT>

<DT><CODE>-ansi -pedantic</CODE>
<DD>
Use ANSI C, and reject any non-ANSI extensions.  These flags help in
writing portable programs that will compile on other systems.
<DT><CODE>-Werror</CODE>
<DD>
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.
<DT><CODE>-Wall</CODE>
<DD>
This turns on a set of warnings for common programming problems.  You
need <CODE>-Wall</CODE>, but it is not enough on its own.
<DT><CODE>-O2</CODE>
<DD>
Turn on optimization.  The warnings for uninitialized variables in
<CODE>-Wall</CODE> rely on the optimizer to analyze the code.  If there is no
optimization then these warnings aren't generated.
<DT><CODE>-W</CODE>
<DD>
This turns on some extra warnings not included in <CODE>-Wall</CODE>, such as
missing return values and comparisons between signed and unsigned
integers.
<DT><CODE>-Wmissing-prototypes -Wstrict-prototypes</CODE>
<DD>
Warn if there are any missing or inconsistent prototypes.  Without
prototypes it is harder to detect problems with incorrect arguments. 
<DT><CODE>-Wtraditional</CODE>
<DD>
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. 
<DT><CODE>-Wconversion</CODE>
<DD>
The main use of this option is to warn about conversions from signed to
unsigned integers.  For example, <CODE>unsigned int x = -1</CODE>.  If you need
to perform such a conversion you can use an explicit cast.
<DT><CODE>-Wshadow</CODE>
<DD>
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.
<DT><CODE>-Wpointer-arith -Wcast-qual -Wcast-align</CODE>
<DD>
These options warn if you try to do pointer arithmetic for types which
don't have a size, such as <CODE>void</CODE>, if you remove a <CODE>const</CODE>
cast from a pointer, or if you cast a pointer to a type which has a
different size, causing an invalid alignment.
<DT><CODE>-Wwrite-strings</CODE>
<DD>
This option gives string constants a <CODE>const</CODE> qualifier so that it
will be a compile-time error to attempt to overwrite them.
<DT><CODE>-fshort-enums</CODE>
<DD>
This option makes the type of <CODE>enum</CODE> as short as possible.  Normally
this makes an <CODE>enum</CODE> different from an <CODE>int</CODE>.  Consequently any
attempts to assign a pointer-to-int to a pointer-to-enum will generate a
cast-alignment warning.
<DT><CODE>-fno-common</CODE>
<DD>
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</CODE> declaration.
<DT><CODE>-Wnested-externs</CODE>
<DD>
This warns if an <CODE>extern</CODE> declaration is encountered within a
function.
<DT><CODE>-Dinline=</CODE>
<DD>
The <CODE>inline</CODE> keyword is not part of ANSI C. Thus if you want to use
<CODE>-ansi</CODE> with a program which uses inline functions you can use this
preprocessor definition to remove the <CODE>inline</CODE> keywords.
<DT><CODE>-g</CODE>
<DD>
It always makes sense to put debugging symbols in the executable so that
you can debug it using <CODE>gdb</CODE>.  The only effect of debugging symbols
is to increase the size of the file, and you can use the <CODE>strip</CODE>
command to remove them later if necessary.
</DL>



<H2><A NAME="SEC522" HREF="gsl-ref_toc.html#TOC522">References and Further Reading</A></H2>

<P>
The following books are essential reading for anyone writing and
debugging numerical programs with GCC and GDB.

</P>

<UL>
<LI>

R.M. Stallman, <CITE>Using and Porting GNU CC</CITE>, Free Software
Foundation, ISBN 1882114388

<LI>

R.M. Stallman, R.H. Pesch, <CITE>Debugging with GDB: The GNU
Source-Level Debugger</CITE>, Free Software Foundation, ISBN 1882114779
</UL>

<P>
For a tutorial introduction to the GNU C Compiler and related programs,
see 

</P>

<UL>
<LI>

B.J. Gough, <CITE>An Introduction to GCC</CITE>, Network Theory Ltd, ISBN
0954161793
</UL>

<P><HR><P>
<p>Go to the <A HREF="gsl-ref_1.html">first</A>, <A HREF="gsl-ref_39.html">previous</A>, <A HREF="gsl-ref_41.html">next</A>, <A HREF="gsl-ref_50.html">last</A> section, <A HREF="gsl-ref_toc.html">table of contents</A>.
</BODY>
</HTML>