Difference between revisions of "Debugging"

From SourceWiki
Jump to navigation Jump to search
Line 13: Line 13:
 
We will start with a pretty common coding problem: we have an array and a loop which access elements of that array in turn.  The problem is that we've made a mistake with our loop and it tries to access elements beyond the boundaries of our array.
 
We will start with a pretty common coding problem: we have an array and a loop which access elements of that array in turn.  The problem is that we've made a mistake with our loop and it tries to access elements beyond the boundaries of our array.
  
Let's take a look and compile up the code using the open-source '''g95''' and '''gfortran''', and  compilers.
+
Here's the saliant parts of the code:
  
We get a '''segmentation fault'''.
+
<pre>
 +
  integer, parameter :: n = 10  ! array size
 +
  integer            :: ii      ! counter
 +
  real, dimension(n) :: x      ! array
 +
</pre>
  
Now the Portland group compiler..not so lucky!
+
<pre>
 +
  ! a loop accessing beyond the array bounds
 +
  do ii = 1, 10000
 +
    x(ii) = x(ii) + float(ii)
 +
    write (*,*) "x(",ii,") is: ", x(ii)
 +
  end do
 +
</pre>
  
Now using the ifort compiler...different again.
+
Let's take a look and compile up the code using the open-source '''g95''' compiler.
  
Interesting, huh?
+
We get a '''segmentation fault''' as soon as we step outside of the array.  "Fine, this is how it should be", you say.  Well, somethimes were not so lucky.  I tried compiling-up the same code using both the Intel and PGI Fortran compilers.  We we're not so lucky.  With PGI, we needed to step outside the array by ''thousands'' of elements before we triggered a segmentation fault.
  
Still using ifort, let's look at the difference when we add:
+
Happily we can check for array bounds problems in a less ''ad hoc'' manner.  Many compilers allow you to incorporate '''run-time''' array-bounds checks into your executable.  Using g95, this is done by supplying the flag '''-fbounds-check''' (or '''-CB''' using Intel).  When we run the program now, we get a much more definitive statement from the compiler (and Intel and PGI don't wait until we're way passed the end of the array either):
  
* -traceback
+
<pre>
* -CB
+
Fortran runtime error: Array element out of bounds: 11 in (1:10), dim=1
 
+
</pre>
to the compilation flags (see Makefile).
 
  
 +
So, by testing our code with the appropriate compiler flags, we can track down occurances of this common problem.
  
 
=Argument Mismatch=
 
=Argument Mismatch=
  
 
The best way to combat this is to put the subroutines into a module.
 
The best way to combat this is to put the subroutines into a module.

Revision as of 09:25, 1 March 2008

Debugging you program: Various techniques

Getting the content for the practical

Login to your favourite linux box and type:

svn export http://source.ggy.bris.ac.uk/subversion-open/debugging/trunk ./debugging

A Common Bug: going beyond the boundaries on array

We will start with a pretty common coding problem: we have an array and a loop which access elements of that array in turn. The problem is that we've made a mistake with our loop and it tries to access elements beyond the boundaries of our array.

Here's the saliant parts of the code:

  integer, parameter :: n = 10  ! array size
  integer            :: ii      ! counter
  real, dimension(n) :: x       ! array
  ! a loop accessing beyond the array bounds
  do ii = 1, 10000
    x(ii) = x(ii) + float(ii)
    write (*,*) "x(",ii,") is: ", x(ii)
  end do

Let's take a look and compile up the code using the open-source g95 compiler.

We get a segmentation fault as soon as we step outside of the array. "Fine, this is how it should be", you say. Well, somethimes were not so lucky. I tried compiling-up the same code using both the Intel and PGI Fortran compilers. We we're not so lucky. With PGI, we needed to step outside the array by thousands of elements before we triggered a segmentation fault.

Happily we can check for array bounds problems in a less ad hoc manner. Many compilers allow you to incorporate run-time array-bounds checks into your executable. Using g95, this is done by supplying the flag -fbounds-check (or -CB using Intel). When we run the program now, we get a much more definitive statement from the compiler (and Intel and PGI don't wait until we're way passed the end of the array either):

Fortran runtime error: Array element out of bounds: 11 in (1:10), dim=1

So, by testing our code with the appropriate compiler flags, we can track down occurances of this common problem.

Argument Mismatch

The best way to combat this is to put the subroutines into a module.