CS170 Debugging with gdb

Using GNU debugger - gdb.

What is gdb?

gdb is GNU debugger which is a program that runs other programs. It allows the user to exercise control over these programs and to examine variables when problems arise. The most popular debugger for UNIX systems is GDB, the GNU debugger. GDB has tons of features, however, you only need to use a few for a start.

Basic features of a debugger

gdb detects the run time error instead of compile time error. The former is logic error, the later is syntax error.

When you execute a program that does not behave as you expected, you need some way to step through the logic other than just looking at your code. Things that you would like to know may be similar to the following:

Using GDB Debugger

Before you can use gdb on a program, you must prepare your program for dubugging with gdb. You must compile it with -g or -ggdb option. The general syntax is
	g++ -g filename.cpp -o executablefile
Under this -g or -ggdb option, g++ creates additional information about the program and deposits it in a symbol table. The debugger must have this symbol table to do its work. You will start gdb by typing in the following command:
	gdb executablefile
where executablefile is the executable version of the program. If you did not use -o option when you compile the program, the executablefile will be a.out.

gdb will give you a prompt that looks like this:(gdb). From this prompt you can use gdb commands such as run or list and so on. To exit the gdb program, just type quit at the (gdb) prompt and then press the enter key.

GDB Commands Summary

The following is a list of the most useful commands inside the gdb.

gdb provides online documentation. Just typing help, you will obtain a list of topics.

"file executable" specifies which program you want to debug.

"run" starts the program running under gdb. The program is the one that you have previously selected with the file command, or on the unix command line when you started gdb. You can give command line arguments to your program on the gdb command line. You can do this the same way you would on the unix command line, except that you are saying run instead of the program name. For example,

run 2048 24 4

You can even do input/output redirection: run > outfile.txt.

"list linenumber" prints out some lines from the source code around linenumber. If you give it the argument function it will print out lines from the beginning of that function.

Just list without any arguments will print out the lines just after the lines that you printed out with the previous list command.

"break" sets a breakpoint in your program.

A ``breakpoint'' is a spot in your program where you would like to temporarily stop execution in order to check the values of variables, or to try to find out where the program is crashing, etc.

"break function" sets the breakpoint at the beginning of function. If your code is in multiple files, you might need to specify filename:function.

"break linenumber" or "break filename:linenumber" sets the breakpoint to the given line number in the source file. Execution will stop before that line has been executed.

"delete" deletes all breakpoints that you have set.
"delete number" deletes breakpoint numbered number. You can find out what number each breakpoint is by doing info breakpoints. (The command info can also be used to find out a lot of other stuff. Do help info for more information.)

"clear function" deletes the breakpoint set at that function. Similarly for linenumber, filename:function, and filename:linenumber.

"step" goes ahead and execute the current source line, and then stop execution again before the next source line.

"next" continues until the next source line in the current function (actually, the current innermost stack frame, to be precise). This is similar to step, except that if the line about to be executed is a function call, then that function call will be completely executed before execution stops again, whereas with step execution will stop at the first line of the function that is called.

"until" is like next, except that if you are at the end of a loop, "until" will continue execution until the loop is exited, whereas "next" will just take you back up to the beginning of the loop. This is convenient if you want to see what happens after the loop, but don't want to step through every iteration.

"print expression" prints out the value of the expression, which could be just a variable name. To print out the first 25 (for example) values in an array called list, you would do
print list[0]@25

"quit" is used to exit the gdb debugger.

Example of using gdb

Here is program called sample.cpp.

#include <iostream>
using namespace std;

int DivideInt(int, int);

int main()
	int x = 5, y= 2;

	cout << " x / y = " << DivideInt(x, y) << endl;

	x = 3;
	y = 0; 

	cout << " x / y = " << DivideInt(x, y) << endl;

	return 0;

int DivideInt(int a, int b)

	return a / b;

To use gdb on this program, you must use -g or -ggdb option when you compile the program.
	g++ -g sample.cpp -o sample
When you run the program, this is what you would get:
A044876[7]% g++ -g sample.cpp -o sample
A044876[8]% sample
 x / y = 2
Floating exception (core dumped)

Core dump occures when a program crashes. Core file is usually large in size. You can use rm command to remove it.

Now let's use gdb to find out the bug.

A044876[9]% gdb sample
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 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 "i386-redhat-linux-gnu"...
(gdb) list
1       #include 
2       using namespace std;
4       int DivideInt(int, int);
6       int main()
7       {
8               int x = 5, y= 2;
10              cout << " x / y = " << DivideInt(x, y) << endl;
(gdb) list
12              x = 3;
13              y = 0;
15              cout << " x / y = " << DivideInt(x, y) << endl;
17              return 0;
18      }
(gdb) list
21      int DivideInt(int a, int b)
22      {
23              return a / b;
24      }
(gdb) run
Starting program: /home/hercules/t/temp1/gdb/sample
 x / y = 2
Program received signal SIGFPE, Arithmetic exception.
0x08048702 in DivideInt(int, int) (a=3, b=0) at sample.cpp:23
23              return a / b;
(gdb) print a
$1 = 3
(gdb) print b
$2 = 0
(gdb) quit
The program is running.  Exit anyway? (y or n) y

The above is only an example of using gdb. We encourage you to try it when you debug your class assignments. You will learn more commands through practice.

Here is a list of the references for using gdb:

CS Dept Home Page
CS Dept Lab Files
CS170 Class Files

Copyright: Department of Computer Science, University of Regina.