Step 2: A simple Debugging session
We will use the debugger to check out the buggy code in buggy.cpp. Follow these steps:
- Compile buggy.cpp using the -g
option. This option tells the compiler and the loader to
store information needed for the debugger:
g++ -g buggy.cpp
- Run the program by typing ./a.out. It should give you a segmentation fault.
Now let's run this program inside the gdb debugger. At
the Unix prompt, type:
gdb a.outAfter gdb starts up, type
runat the gdb prompt. You should get a segmentation fault again.
After the segmentation fault, gdb prints out lots of
information. Look at the lines:
Program received signal SIGSEGV, Segmentation fault. 0x0000000000400888 in main () at buggy.cpp:12 12 A[i/2] = i*i ;
This says the program crashed while executing main() on line 12 of the file buggy.cpp. It also helpfully prints out line 12 for you.
Using gdb, you can look at the memory contents of your program just after the segmentation fault. This is convenient if running your program requires several steps involving user I/O. At any time while running gdb, you can type the command where to find out where you are in the program.
If all you remember about gdb is the "where" command, you still have a very useful tool in debugging pointer errors.
- Of course, we don't memorize our programs. The list
command shows you the source code. Try these variations of
the list command:
list 12 list main list 1,18If you type list right after another list command, it shows you another 10 lines below the previously listed lines.
- The command help list will tell you more about list. In general, "help" followed by a topic or a command will give you documentation on that topic. Typing just help will give you a list of topics.
- To see the value of variables and objects in the program, use
the print command. Try these different print commands
(you can also use p as a shortcut for print):
print i print A[i] print A print &A print &i print &AConclusion: somehow the value of i has grown so large that accessing A[i] causes a segmentation fault.
- Now we will re-run the program to see what
happened. In gdb we can set breakpoints which stop
the program at critical places. Type:
break 12This stops the execution of the program before the code on line 12 is executed. Type run to start the program running. You should see something like:
Breakpoint 1, main () at buggy.cpp:12 12 A[i] = i*i ;Type print A and print i to see that the values of A and i are as expected.
To execute the code in line 12, type:
stepThe step command executes one line of source code and shows you the next line. Print out A and i again to see the effects of line 12.
- We can continue to step through the program this way, but it is
simpler to issue the continue command (or
just c for short).
continueThis runs the program until the next breakpoint.
We can keep typing continue and print
commands this way, but all those prints get a bit tedious. Type:
display A display iThis tells the compiler to print out A and i whenever it stops at a breakpoint.
- Type continue again. Now you see the next iteration of the while loop. To continue again, you just have to hit the return key. Notice that the value of i eventually grows quite large. How did that happen?
- If you missed the iteration where the value of i ballooned, type kill to stop running the program and run to restart it. Your breakpoints and display items are still intact.
- To make sure you don't blow past the critical iteration of the while loop again, stop at the iteration when i is 20. Then use step. You don't have to type step every time. After the first step, hitting the return key is equivalent to typing step.
- Now type p &A and p &i. Notice that these are the same hexadecimal (base 16) values (or should be on GL).
- Now you can quit, using quit.
- Compile using the -g option, then gdb a.out
- Use list to see your source code
- Use break to set breakpoints
- Start running with run
- Use print to see values
- display prints automatically
- Use step to execute one more line
- Use continue to execute until the next breakpoint
- The commands kill and quit do what you think
info breakpoints info displayYou can remove all breakpoints using delete or individual breakpoints using delete 1, delete 2, ... (Use the breakpoint number from the info list.) Sometimes you just want to temporary disable a breakpoint. You can do that with disable 1, disable 2, ... To enable the breakpoint again, use enable 1, enable 2, ...
To list your display items, info display. Use undisplay to remove a display item. Use disable display 1, disable display 2,... to temporarily disable a display item.