Debugger Example

 

Use the following source code:

 

#include<iostream>

using namespace std;

 

const int BIGNUM = 5000;

 

enum Boolean { FALSE = 0, TRUE = 1 };

 

void index_to_the_moon ( int [] );

 

int main ()

{

     int intary [10];

 

     index_to_the_moon ( intary );

 

     return ( TRUE );

}

 

void index_to_the_moon ( int ary [] )

{

     for ( int index =0; index < BIGNUM; ++index )

          ary [index] = index;

}

 

The program must be compiled with the –g compiler flag to include debugging information.

 

$ g++ –g –o debugme debugme.C

 

Now run the program and watch it crash!!!  It gives the wonderful Segmentation fault message.  Next we can start the debugger and find out where the program crashed.  Use the command:

 

$ gdb debugme


The output you get will look like the following:

 

$ gdb debugger

GNU gdb 4.18

Copyright 1998 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "alpha-mandrake-linux"...

(gdb)

 

Now run the program using the debugger:

 

(gdb) run

Starting program: /students/gamradtk/csc250/debugger

warning: Unable to find dynamic linker breakpoint function.

GDB will be unable to debug shared library initializers

and track explicitly loaded dynamic code.

 

Program received signal SIGSEGV, Segmentation fault.

0x120000884 in index_to_the_moon (ary=0x11ffff830) at debugger.C:21

21          ary [index] = index;

(gdb)

 

This tells us that the program crashed on line 21 attempting to assign the value index to the array.  We can use the backtrace command to examine how we got there as shown below:

 

(gdb) backtrace

#0  0x120000884 in index_to_the_moon (ary=0x11ffff830) at debugger.C:21

#1  0x120000804 in main () at debugger.C:13

(gdb)

 

To look at the offending code we can use the list command.  The format is list[m,n].  m and n are the starting and ending line numbers you want.  A list with no parameters just list the surrounding 10 lines of code as illustrated in the following:

 

(gdb) list

16      }

17

18      void index_to_the_moon ( int ary [] )

19      {

20        for ( int index =0; index < BIGNUM; ++index )

21          ary [index] = index;

22      }

(gdb)

 

Examing Data

 

One of gdb’s features is the ability to display both the value and type of a variable or an expression.  It will print the value of any expression that is legal in the language being debugged.  The command is print.  The following are some print commands and their results:

 

(gdb) print index

$1 = 500

(gdb) print ary[index]

$2 = 1179403647

(gdb) print ary[index-1]

$3 = 499

 

With array’s you can display individual elements, the entire array, or a range of array values using the following commands:

 

print ary@10         - print the first ten values pointed to by the ary pointer

print ary[5]            - print the element in position five

print ary[0]@10       - print ten elements starting at ary[0]

print ary[2]@3        - print three elements starting at ary[2]

 

One can use the command whatis to determine the type of a variable as shown:

 

(gdb) whatis index

type = int

(gdb) whatis ary

type = int *

(gdb) whatis index_to_the_moon

type = void (int *)

(gdb)

 

Setting Breakpoints

 

As you debug code it is nice to be able to run the code up to a certain point and then stop the execution so that you can examine individual lines of code as they execute.  The break command can be used to set breakpoints as follows:

 

(gdb) break <linenum>

 

or

 

(gdb) break <funcname>

 

This stops the code when a particular line or function is reached, when using multiple file programs you can also precede the line number or the function name with a file name as in:

 

(gdb) break <filename:linenum>

 

or

 

(gdb) break <filename:funcname>

 

Conditional breaks are generally more useful.  This allows us to stop when a condition has been met.  The correct syntax is:

 

(gdb) break <linenum or funcname> if <expr>

 

The following example shows this:

 

(gdb) break 21 if index == 15

Breakpoint 1 at 0x12000086c: file debugger.C, line 21.

(gdb) run

Starting program: /students/gamradtk/csc250/debugger

warning: Unable to find dynamic linker breakpoint function.

GDB will be unable to debug shared library initializers

and track explicitly loaded dynamic code.

 

Breakpoint 1, index_to_the_moon (ary=0x11ffff830) at debugger.C:21

21          ary [index] = index;

(gdb)

 

You may use the info breakpoints command to examine current breakpoints and delete, disable and enable to remove or disable breakpoints.

 

Running code in the debugger

 

The following commands are used to step through and run debugger code:

 

run             - run the code, stop at the first breakpoint if it exists

next            - step over function calls and execute the next line of code

step            - step into function calls and execute the next line of code

continue      - continue running the code until the end or next breakpoint

quit       - exit out of the debugger