Difference between revisions of "Debugging"
Line 4: | Line 4: | ||
=Introduction= | =Introduction= | ||
− | Humans can be variously ingenious, inspired, careful | + | Humans can be variously ingenious, inspired, careful, persistent and many things besides. All of these character traits can be called upon when writing software. There is one aspect of human nature we can be certain of, however: '''We err'''. We make mistakes; muck it up; break stuff. No amount of technology, know-how or experience will change this. From time-to-time, we get it wrong. |
This isn't as bad as it seems, however. If we never made a mistake, how would be learn? Making mistakes is vital to our progress. That said, we also need our programs to work correctly. We want our weather and climate models to accurately predict the future. We want our banking software not to 'lose' our money. We want stuff to work. | This isn't as bad as it seems, however. If we never made a mistake, how would be learn? Making mistakes is vital to our progress. That said, we also need our programs to work correctly. We want our weather and climate models to accurately predict the future. We want our banking software not to 'lose' our money. We want stuff to work. |
Revision as of 10:20, 3 March 2008
Debugging you program: Various techniques
Introduction
Humans can be variously ingenious, inspired, careful, persistent and many things besides. All of these character traits can be called upon when writing software. There is one aspect of human nature we can be certain of, however: We err. We make mistakes; muck it up; break stuff. No amount of technology, know-how or experience will change this. From time-to-time, we get it wrong.
This isn't as bad as it seems, however. If we never made a mistake, how would be learn? Making mistakes is vital to our progress. That said, we also need our programs to work correctly. We want our weather and climate models to accurately predict the future. We want our banking software not to 'lose' our money. We want stuff to work.
OK, given that we're going to get bugs and that we don't really want them, this workshop is focussed upon finding them and correcting them--the art of debugging. Approached rashly, debugging can a a torrid and despairing task. With some of the right tools and a systematic approach, however, debugging can be a rewarding task. As we alluded to earlier, debugging is a learning process and as you grapple with your own projects, you will have a great many of those, "aha!" and "oh, I see!" moments. Not quite a joy, but satisfying at the very least!
Getting the content for the practical
OK, let's make a start. 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.
Let's visit our example:
cd debugging/examples/example1
Here's the saliant parts of the code, from array_bounds.f90:
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.
Testing
We need to test our code to see where the bugs are!