The GNU Debugger
Background
The GNU Debugger is a command-line debugging program that allows a user to step through the execution of a program and monitor its internal state. It can be used with C, C++, Fortran and Modula-2, although I only have experience using it with C.
Joshua Rampersad gave and extremely useful lecture on the basics of GDB at the University of Waterloo, which is available on YouTube. I originally learned GDB from that lecture, and its influence is likely seen in the content and structure of this article.
Running GDB
When using GDB, C programs should generally be compiled with the -g
flag. This will add debugging information to the output file. The output will be a larger file than a normal binary because it will contain the information necessary for GDB to determine line number and line content information.
$
gcc -g myProgram.c
Once the program has been compiled, the GDB debugger can be entered as shown below.
$
gdb myExecutable.out
GNU gdb (GDB) 14.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from myExecutable.out...
(gdb)
If the program requires command-line arguments, they must be assigned using the set
command as shown in the table below.
The Commands
Once a program is loaded in GDB, the following commands can be used to run and debug it.
set args arg1 arg2 etc. | if the program requires command-line arguments, they must be entered this way |
run | run the program from the beginning |
break n | set a breakpoint at line n |
break functionName | set a breakpoint at function functionName |
next | run the next line |
list | show the lines surrounding the current line |
print x | print the status of variable x |
quit | quit GDB |
up | move up the call stack |
down | move down the call stack |
display x | keep displaying the status of variable x at every step |
undisplay 1 | stop displaying the status of variable number 1 |
backtrace | show backtrace |
step | advance to the next line, even if it is inside a function |
continue | run to the next breakpoint |
finish | run until the current function returns |
watch x | run until the value of x changes and print the change |
info breakpoints | list all breakpoints, which will show their numbers |
delete 1 | delete breakpoint 1 |
delete | delete all breakpoints |
whatis x | print x's type |
target record-full | begin recording, allowing reverse-next to be used |
reverse-next | undo next (only works after target record-full was run) |
set var x = 0 | set the value of x to 0 |