GNU Debugger
This page has information to get you started with the GNU Debugger, which is the gdb
command on the server.
Compiling and Starting gdb
To run a C program in the GNU Debugger, you use the gdb
command. First you need to compile the file with the -g
flag so that it contains debugging information. We use the file args_add4.c as an example. You can download this file, or you can copy/paste the code into a text editor and save it as args_add4.c. When debugging and testing code, it is also a good idea to turn on all warnings (with the -Wall
option) and turn off compiler optimization (with the -O0
option).
To compile with debugging information, you run:
gcc -g -Wall -O0 args_add4.c -o args_add4.o
To run the program in gdb
, you run gdb
giving the .o file name as a parameter:
gdb args_add4.o
This has loaded the program into the debugger.
Commands in gdb
The rest of this article is assuming you have started gdb
as indicated above. You interact with gdb
by typing commands after you have started the program.
To run the program you use the run command and give any command-line arguments after run. For example:
run 1 2 3
When you type enter, the program will run. If it crashes, the debugger stops the program from crashing so you can take a look at what is happening. When we run the above, we see the following.
(gdb) run 1 2 3 Starting program: /net/web/learn/C/fix_errors/args_add4.o 1 2 3 Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7de5633 in ____strtod_l_internal () from /lib64/libc.so.6 (gdb)
There has been a segmentation fault. We can see information about the status of the program by typing the backtrace command:
(gdb) backtrace #0 0x00007ffff7de5633 in ____strtod_l_internal () from /lib64/libc.so.6 #1 0x0000000000401174 in main (argc=4, argv=0x7fffffffdfa8) at args_add4.c:15 (gdb)
The problem is at line 15 in the program. We can see what is at line 15 either by looking at the file in our text editor, or using the list command in gdb
.
(gdb) list 15 10 #include <stdlib.h> 11 12 int main(int argc, char *argv[]) { 13 float total = 0; 14 for(int i=1; i < argc; i--) { 15 total += atof(argv[i]); 16 } 17 printf("%f\n", total); 18 19 return 0; (gdb)
Probably the segmentation fault is the argv[i]
on line 15. We can see what the value of i is by setting the debugger to be using the "stack frame" that has this value (frame #1 as indicated on the output after we ran the backtrace command) and then using the print command.
(gdb) frame 1 #1 0x0000000000401174 in main (argc=4, argv=0x7fffffffdfa8) at args_add4.c:15 15 total += atof(argv[i]); (gdb) print i $1 = -1 (gdb)
This is definitely a problem - the index i should not be negative if we are using it as an array index. Looking back at the printout of the code, the mistake is in line 14: rather than i--
, the loop increment should be i++
.
gdb Commands
The following are a few key commands to get you started in gdb
.
run arg1 arg2 ...
(can be abbreviated asr
) - run the program that is being debugged, giving it command-line argumentsarg1 arg2 ...
backtrace
(can be abbreviatedbt
) - print a trace of the stack frame, which is a history of which functions have been called and still haven't completedframe i
(can be abbreviatedf
) - set the debugger to be using the given (i
) stack frameprint expr
(can be abbreviatedp
) - evaluate the given expression and print its value (e.g., can be used to print the value of a variable)quit
(can be abbreviatedq
) - quit the debugger(s)tep
- step one line at a time (going into a function if the next line is a function call).(c)ontinue
- continue execution.break file_name.c:100
- set a break point at line 100 in file_name.cbreak function_name
- set a break point on function_name.
For more information, search online for GDB tutorials, reference sheets, and documentation. The official documentation is here - https://www.sourceware.org/gdb/documentation/ A good quick start is https://web.eecs.umich.edu/~sugih/pointers/gdbQS.html