Debugging

Debugging Segmenation Violations / Faults ("segfaults")

Segmentation faults are one of the most common errors encountered by programs under development.  A segmentation fault indicates that a program attempted to use a piece of memory that was not available or in a way that was not allowed.  Segmentation faults are notoriously problematic, especially because a program experiencing one may not fail immediately, but may continue running for a period of time before failing, or may appear to complete despite the error.

Segmentation faults often arise from a code error involving pointers.  One of the most common sources of the error is reading or writing "off the end" of an array.  For example, consider an array of doubles of length 10 in C++, where the array index runs from 0 to 9.  The following C++ code snippet would cause a segfault:

    for(int i=0; i<11; i++){
        sample_array[i] = 5.0;
    }

This loop would cause a segmentation fault because it attempts to write the value 5.0 to sample_array[10]  which is actually the eleventh place in the array (the array index begins at 0 and runs to 9); the array is only ten places long so sample_array[10] does not exist, and the write is invalid.

There are a number of tools that can assist in locating the source of a segfault so that it may be fixed.  One such tool is the memory debugger named Valgrind.  Valgrind is a GNU tool, and to use it the code being analyzed must have been compiled with one of the GNU compilers (gfortran, gcc, g++) using the -g compiling option.  For example, to compile a C++ program in preparation for Valgrind analysis the command would be:

g++ -g source_code.cpp

The Valgrind option named memcheck is useful to locate the source of a segfault.  The command to load an executable named a.out into Valgrind to perform a memcheck analysis would be:

valgrind --tool=memcheck ./a.out

The executable should here be passed any necessary input parameters needed for a normal execution.  The program will then execute with Valgrind continously watching the memory behavior.  If an illegal memory read or write occurs Valgrind will produce an error message with information about the place in the code where the error occurred.

Running a program within Valgrind for analysis in this way causes significantly slower execution.  More information on Valgrind and its options can be found at: http://valgrind.org/docs/manual/index.html