Using GDB
Before you can use a symbolic debugger, you must compile your program with the debug flag. This tells the compiler to insert debugging information the debugger will use. On Franklin's system, you do that by using the -g flag when compiling your program. So if your source file is named main.cpp, you would compile it like this:
g++ -g main.cpp
Once you have a program compiled with the -g flag, you can use gdb, the debugger available on Franklin's system. You start it by passing it the name of the program to run:
gdb a.out
gdb will print out some copyright information and then leave you at the gdb prompt:
(gdb)
At this prompt you can use various gdb commands.
Breakpoints: Breakpoints tell gdb to stop executing your program when it gets to a certain line of code or a certain function. For example, to tell gdb to stop at line 15 in your program, you would type in (what you type is in italics):
(gdb) break 15
To stop at a function called calcTime, you would type:
(gdb) break calcTime
Running: Running a program can take several forms. The easiest is to just tell gdb to run your program:
(gdb) run
This starts executing your program, and will not stop until your program ends, crashes, or a breakpoint is hit.
Once you've hit a breakpoint, you may want to execute single lines of your program. There are two primary ways of doing this. One way is to execute a single line of the program and move to the next sequentially numbered line. If the current line is a function call, this will execute the function and then place you on the next line of code. You do this by typing:
(gdb) next
The other way is if you want to step into function calls. You do this by typing:
(gdb) step
Step will, if the current line is a function call, place you on the first line of that function.
To continue running a program once a breakpoint has been hit, type:
(gdb) cont
This will run the program until the next breakpoint is hit, the program ends, or the program crashes.
Examining Variables: Once you've hit a breakpoint, you probably will want to see what values your variables contain. You do this by typing (assuming that there is a variable x we want to examine):
(gdb) print x
Examining the Call Stack: The call stack contains the list of function calls made to get to where you're at in the program. Examining the stack is most often useful when you're tracking down a coredump. Often the problem isn't with the line where the coredump happens, but in the calling function.
To examine the call stack, type:
(gdb) bt
To examine variables in the calling function, type:
(gdb) up
And then use the print command normally. To get back to where you were at, type:
(gdb) down
If you want to quit the debugger, you type:
(gdb) quit
Getting Help
gdb has many more options than discussed here. You can use the help command like this:
(gdb) help
This will give you a listing of subjects you can get help on.
Using gdb to diagnose program crashes
The following technique should be used anytime you have a program which 'crashes'. Do not ask for help with a program crash until you have done the following!
- Compile the program with -g so you can use gdb
- Start gdb with the name of your program (i.e. gdb a.out)
- At the (gdb) prompt, type run and hit Enter.
- When your program crashes, gdb will tell you the line of code that had a problem. Often, this line of code will be inside the C++ standard library. The problem is not in the C++ standard library, it is in your code; most likely you are passing something bad to the standard library.
- At the (gdb) prompt, type bt to get a list of function calls made before the crash. The top of the list should be the line where the program crashed. The next line is where that function was called from, and so on down the list. Find the first line of the stack trace that is inside code you wrote.
- At the (gdb) prompt, type up and hit Enter. This will take you to the line of code that called the function that crashed. Continue typing up and hitting Enter until you get to code you wrote.
- This is, probably, where the problem is. Use the print command to look at the contents of variables you are passing to the function that crashed. If you are in a class, use print this to make certain that the class is not null.