Valgrind http://valgrind.org/ is a powerful memory debugging tool which makes debugging many critical and otherwise hard to find glitches in programs next-to-trivial. To use valgrind, simply run the program you want to debug as

valgrind [valgrind options] program [program options]

Valgrind will then load the program and execute it in a virtual machine where it can trace all memory accesses. The result will be running much slower, but valgrind will give you a warning message every time it thinks that something is going wrong. If you have compiled your program with debugging symbols enabled (-g with most compilers), the tool will also give you the source file and line number in which the error occurred. Other than the warnings and the reduced speed, the program will run as usual. Some of the nastiest bugs found by valgrind are:

Array bounds violations The index of an array excesses its bounds. If one is lucky, the program segfaults, but in most cases, the result is either a semi-arbitrary value (if the array is read) or, even worse, silent corruption of other variables (if the array is written). Most compilers can be instructed to check for this at runtime at the expense of processing time being lost due to the overhead of checking every access. Valgrind will warn you about an 'invalid read / write' when this happens.

Invalid pointers An invalid pointer is dereferenced; as above, the consequences can range from a segfault to corruption. This kind of bug is virtually impossible to introduce in FORTRAN 77 due to the absence of pointers and dynamic memory management, but can occur in FORTRAN 90+ and is abundant in C and to a lesser degree also in C++. Again, valgrind will warn you if your program fails this way.

Use of uninitialized variables A variable is read which has not been assigned a value. This happens easily, and the resulting value depends on the compiler and execution conditions. As this does not necessarily signify an error in the program logic, valgrind does not immediately warn you about this, but it tracks the presence of the invalid value through your problem and tells you as soon as the program flow depends on it. For example, an if statement involving an undefined value will generate an 'conditional jump depends on undefined value' error. You can use the valgrind option –track-origins=yes to track down the origin of the undefined value, but this will slow down program execution further.

Undefined function results A function returns without defining a return value, the result is depends on the previous contents of the stack. Valgrind treats those just as undefined values (see above).

Memory leaks A piece of memory is allocated, but the value of the pointer is lost and the memory is never freed. If it happens in loops, this can lead to gigantic amounts of memory being lost over time. Again, this is impossible in FORTRAN 77 due to the missing support for dynamic memory management, but if you use another language and operate on data structures like lists and trees, this is a very common problem. At the end of the program, valgrind gives you a list of memory areas which are lost and where in the code they were originally allocated.

Valgrind only reports errors up to some limit; after that, it stops counting and tells you just 'to fix your code' :) Also, it can happen that valgrind detects errors originating from external libraries (FORTRAN runtime for example). While one should make sure that those are not triggered by invalid calls to external functions, this usually indicates harmless bugs or cases of sloppiness in the external code.

Oh, most important: valgrind is installed and ready-to-use on our machines :)