Debugging a Program that Crashes

Consider the following example "crash1.C"

  #include 

  using namespace std;

  int divint(int, int);

  int main() {
    int x = 5, y = 2;
    cout << divint(x, y);
    x =3; y = 0;
    cout << divint(x, y);
    return 0;
  }
  int divint(int a, int b)
  {
    return a / b;
  } 
To enable debugging, the program must be compiled with the -g option.
  g++ -g crash1.C -o crash1 
When I run this on my Linux machine, it produces the result:
  Floating point exception (core dumped)
An error like this can usually be debugged very easily in the following manner using gdb, the GNU debugger.
  # At the command line type
  > gdb crash1
    # Gdb prints summary information and then the (gdb) prompt

    (gdb) r
    Program received signal SIGFPE, Arithmetic exception.
    0x08048681 in divint(int, int) (a=3, b=0) at crash1.C:21
    21        return a / b;
    # 'r' runs the program inside the debugger
    # In this case the program crashed and gdb prints out some
    # relevant information.  In particular, it crashed trying
    # to execute line 21 of crash1.C.  The function parameters
    # 'a' and 'b' had values 3 and 0 respectively.

    (gdb) l
    # l is short for 'list'.  Useful for seeing the context of
    # the crash, lists code lines near around 21 of crash.C

    (gdb) where
    #0  0x08048681 in divint(int, int) (a=3, b=0) at crash1.C:21
    #1  0x08048654 in main () at crash1.C:13
    # Equivalent to 'bt' or backtrace.  Produces what is known
    # as a 'stack trace'.  Read this as follows:  The crash occurred
    # in the function divint at line 21 of crash1.C.  This, in turn,
    # was called from the function main at line 13 of crash1.C

    (gdb) up
    # Move from the default level '0' of the stack trace up one level
    # to level 1.

    (gdb) list
    # list now lists the code lines near line 13 of crash1.C

    (gdb) p x
    # print the value of the local (to main) variable x 
In this example, it is fairly obvious that the crash occurs because of the attempt to divide an integer by 0 (this will never cause a crash if the variables are floating point). The main point is that gdb will locate exactly where the error occurs and give access to the values of all of program variables as well as the stack trace at the time of the crash.

By default, programs produce "core dumps" when they crash. This means that a crash produces a large file named 'core' or perhaps 'core.16345' in the directory where the program was run. This can result in many large core files in a user's directories and subdirectories, so the default settings for most users in Statistics disable the creation of core files. Core files contain information useful for debugging a crash, but they are often not needed as all of the core file information about a crash can be reproduced simply by running the program in gdb as above. To debug a program 'crash1' hat has crashed and produced a core file named 'core', type the following at the command line:

  gdb crash1 core 
As this is mostly equivalent to starting gdb and typing the 'r' command, all of the commands above could now be used to debug the file.

The main reason one would want to use a core file is if one cannot run the file in the debugger. For example, a program may run for several hours before crashing and the user might not be able to stay logged on the entire time. In this case the program should be run in the background, and the core dump can be debugged at a later time.