Debug with GDB#

Load an Executable#

Using GDB to debug requires it recognizes a program’s debug symbols. By compiling with -g option, GDB will understand what source code looks like after loading an executable file:

$ gcc -g -Wall -Werror foo.c # compile with -g option
$ gdb ./a.out  # load all symbols of a.out into GDB

Text User Interface#

Text User Interface (TUI) allows developers to visualize source code and to debug like using the Integrated Development Environment (IDE) to trace problems. For a beginner, entering the TUI mode is more understandable than the command line mode. The following key bindings are the most common usages for interacting with TUI.

  1. Ctrl x + a - Enter or leave the TUI mode

  2. Ctrl x + o - Switch the active window

  3. Ctrl x + 1 - Display one window (e.g., source code + GDB shell)

  4. Ctrl x + 2 - Display two windows (e.g., source code + GDB shell + assembly)

  5. Ctrl l - Refresh window

Basic Commands#

Start/Stop a program

  1. start - Run an executable file and stop at the beginning

  2. run / r - Run an executable file until finish or stop at a breakpoint

  3. step / s - Run a program step by step with entering a function

  4. next / n - Run a program step by step without entering a function

  5. continue / c - Run a program until finish or stop at a breakpoint

  6. finish - Step out of the current function

Set Breakpoints

  1. b line - Set a breakpoint at the given line in the current file

  2. b file: line - Set a breakpoint at the given line in a given file

  3. b … if cond - Set a breakpoint when the condition is true

  4. clear line - Delete a breakpoint at the given line in the current file

  5. clear file: line - Delete a breakpoint at giving a line in a given file

  6. info breakpoints - Display breakpoints status

  7. enable breakpoints - Enable breakpoints

  8. disable breakpoints - Disable breakpoints

  9. watch cond - Set a watchpoint for inspecting a value

Display Stack

  1. backtrace / bt - Display current stack

  2. frame / f framenum - Select a frame and inspect its status

  3. where - Display the current stack and the line

Print Variables

  1. print / p var - Print value of the given variable

  2. ptype var - Print type info of the given variable

  3. info args - Print function arguments

  4. info locals - Print all local variables

Reverse Run

  1. record - Start recording each instruction step

  2. record stop - Stop recording

  3. rn - Reverse next

  4. rs - Reverse step

int main(int argc, char *argv[]) {
    int out = 0;
    for (int i = 0; i < 10; ++i) {
        out = i * i;
    }
    return out;
}
(gdb) b main
(gdb) r
Starting program: /home/ubuntu/a.out

Breakpoint 1, main (argc=21845, argv=0x0) at test.cc:2
2       {
(gdb) record
...
(gdb) n
(gdb) p out
$1 = 1
(gdb) rn
(gdb) rn
(gdb) p out
$2 = 0

Define a Function

GDB provides an original way for developers to define a customized function. The following snippet shows how to define a function to display the information of the current stack.

(gdb) define sf
Type commands for definition of "sf".
End with a line saying just "end".
>where
>info args
>info locals
>end

Display Memory Contents#

int main() {
    char arr[100] = "1234567890abcdefghijklmnopqrstuvwxyz";
    return 0;
}
(gdb) " x/[format] [address expression]
(gdb) " x/[len][format] [address expression]
(gdb) x/s arr
0x7fffffffe620:     "1234567890abcdefghijklmnopqrstuvwxyz"
(gdb) x/10c arr
(gdb) x/5c arr
0x7fffffffe620:     49 '1'  50 '2'  51 '3'  52 '4'  53 '5'
(gdb) x/5b arr
0x7fffffffe620:     0x31    0x32    0x33    0x34    0x35