Appendix D: GDB Quick Reference
GDB is the GNU Debugger. It's the primary tool for finding segfaults, inspecting data structures, and understanding what your C and Rust programs actually do at runtime.
Starting GDB
# Compile with debug symbols
$ gcc -g -O0 -o myapp myapp.c
$ rustc -g -o myapp myapp.rs
# Start GDB
$ gdb ./myapp
# Start with arguments
$ gdb --args ./myapp arg1 arg2
# Attach to running process
$ gdb -p <pid>
# Analyze a core dump
$ gdb ./myapp core
# Start in TUI (text user interface) mode
$ gdb -tui ./myapp
Essential Commands
Running
| Command | Short | Action |
|---|---|---|
run | r | Start the program |
run arg1 arg2 | r arg1 arg2 | Start with arguments |
continue | c | Continue after breakpoint |
kill | Kill the running program | |
quit | q | Exit GDB |
Breakpoints
| Command | Short | Action |
|---|---|---|
break main | b main | Break at function |
break file.c:42 | b file.c:42 | Break at line |
break *0x4005a0 | b *0x4005a0 | Break at address |
break func if x > 10 | Conditional breakpoint | |
tbreak main | tb main | Temporary (one-shot) breakpoint |
info breakpoints | i b | List breakpoints |
delete 1 | d 1 | Delete breakpoint #1 |
delete | d | Delete all breakpoints |
disable 1 | dis 1 | Disable breakpoint #1 |
enable 1 | en 1 | Enable breakpoint #1 |
Stepping
| Command | Short | Action |
|---|---|---|
next | n | Step over (next line) |
step | s | Step into function |
finish | fin | Run until current function returns |
until 50 | u 50 | Run until line 50 |
nexti | ni | Step one instruction (over calls) |
stepi | si | Step one instruction (into calls) |
Examining Variables
| Command | Action |
|---|---|
print x | Print variable x |
print *ptr | Dereference pointer |
print arr[5] | Array element |
print sizeof(x) | Size of variable |
print/x val | Print in hex |
print/t val | Print in binary |
print/d val | Print as decimal |
print/c val | Print as character |
print (struct foo *)ptr | Cast and print |
display x | Print x every time we stop |
undisplay 1 | Remove display #1 |
info locals | All local variables |
info args | Function arguments |
ptype var | Show type of variable |
whatis var | Short type description |
Examining Memory
x/FMT ADDRESS
Format: x/[count][format][size]
count: number of items
format: x (hex), d (decimal), u (unsigned), o (octal),
t (binary), c (char), s (string), i (instruction)
size: b (byte), h (halfword=2), w (word=4), g (giant=8)
| Command | Action |
|---|---|
x/16xb ptr | 16 bytes in hex |
x/4xw ptr | 4 words (32-bit) in hex |
x/s str | Print as C string |
x/10i $pc | 10 instructions at PC |
x/gx &var | 8-byte value in hex |
Example session:
(gdb) x/32xb buffer
0x7fffffffe400: 0x48 0x65 0x6c 0x6c 0x6f 0x00 0x00 0x00
0x7fffffffe408: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffe410: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffe418: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Watchpoints
Watchpoints stop when a variable's value changes.
| Command | Action |
|---|---|
watch x | Break when x changes |
watch *0x601040 | Break when memory at address changes |
rwatch x | Break when x is read |
awatch x | Break on read or write |
info watchpoints | List watchpoints |
Watchpoints are hardware-assisted (limited number, typically 4) or software-assisted (very slow).
Backtrace and Stack
| Command | Short | Action |
|---|---|---|
backtrace | bt | Show call stack |
backtrace full | bt full | Stack with local vars |
frame 3 | f 3 | Select stack frame #3 |
up | Move up one frame | |
down | Move down one frame | |
info frame | i f | Detailed frame info |
info stack | i s | Stack summary |
Threads
| Command | Action |
|---|---|
info threads | List all threads |
thread 2 | Switch to thread 2 |
thread apply all bt | Backtrace all threads |
thread apply all print var | Print var in all threads |
set scheduler-locking on | Only run current thread |
set scheduler-locking off | Run all threads |
TUI Mode
TUI (Text User Interface) shows source code alongside the command line.
# Start in TUI mode
$ gdb -tui ./myapp
# Toggle TUI in running session
(gdb) tui enable
(gdb) tui disable
# Or press Ctrl+X then A to toggle
# Switch layouts
(gdb) layout src # source code
(gdb) layout asm # assembly
(gdb) layout split # source + assembly
(gdb) layout regs # registers
Refresh the screen if it gets corrupted: Ctrl+L
Common Workflows
Finding a Segfault
$ gcc -g -O0 -o buggy buggy.c
$ gdb ./buggy
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400556 in process_data (ptr=0x0) at buggy.c:15
15 *ptr = 42;
(gdb) bt
#0 0x0000000000400556 in process_data (ptr=0x0) at buggy.c:15
#1 0x0000000000400589 in main () at buggy.c:22
(gdb) print ptr
$1 = (int *) 0x0
(gdb) frame 1
#1 0x0000000000400589 in main () at buggy.c:22
(gdb) info locals
data = 0x0
The backtrace tells you: process_data was called with a NULL pointer from
main at line 22.
Inspecting a Linked List
(gdb) print *head
$1 = {value = 10, next = 0x602040}
(gdb) print *head->next
$2 = {value = 20, next = 0x602060}
(gdb) print *head->next->next
$3 = {value = 30, next = 0x0}
Or use a loop:
(gdb) set $node = head
(gdb) while $node
> print $node->value
> set $node = $node->next
> end
$4 = 10
$5 = 20
$6 = 30
Debugging Multi-Threaded Programs
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7f... "main" in main () at server.c:45
2 Thread 0x7f... "worker" in handle_client () at server.c:28
3 Thread 0x7f... "worker" in recv () from /lib/...
(gdb) thread 2
(gdb) bt
#0 handle_client (arg=0x602010) at server.c:28
#1 0x00007ffff... in start_thread ()
(gdb) thread apply all bt
Finding Memory Corruption
Use watchpoints to find what's overwriting a variable:
(gdb) break main
(gdb) run
(gdb) watch my_variable
(gdb) continue
Hardware watchpoint 2: my_variable
Old value = 42
New value = 0
0x000000000040066a in corrupt_function () at bug.c:33
Examining struct Layout
(gdb) ptype struct sockaddr_in
type = struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
(gdb) print sizeof(struct sockaddr_in)
$1 = 16
Rust-Specific GDB Tips
Compiling Rust for GDB
# Debug build (default, includes symbols)
$ cargo build
$ gdb ./target/debug/myapp
# Release with debug info
# In Cargo.toml:
# [profile.release]
# debug = true
$ cargo build --release
$ gdb ./target/release/myapp
Rust Type Names in GDB
Rust types appear with their full path:
(gdb) ptype v
type = alloc::vec::Vec<i32, alloc::alloc::Global>
Printing Rust Types
(gdb) print v
$1 = Vec(size=3) = {1, 2, 3}
(gdb) print s
$2 = "hello world"
(gdb) print opt
$3 = core::option::Option<i32>::Some(42)
(gdb) print result
$4 = core::result::Result<i32, ...>::Ok(10)
GDB has pretty-printers for common Rust types (Vec, String, Option, Result, HashMap) when Rust's GDB extensions are installed.
Rust Mangled Names
Rust function names are mangled. Use:
(gdb) break myapp::main
(gdb) break myapp::module::function_name
Or with tab completion:
(gdb) break myapp::<TAB><TAB>
Printing Enum Variants
(gdb) print my_enum
$1 = myapp::State::Running(42)
Unwinding Through Panics
(gdb) break rust_panic
(gdb) run
(gdb) bt
#0 std::panicking::begin_panic ()
#1 myapp::risky_function () at src/main.rs:15
#2 myapp::main () at src/main.rs:8
GDB Configuration
Put frequently used settings in ~/.gdbinit:
# ~/.gdbinit
set print pretty on
set print array on
set pagination off
set history save on
set history filename ~/.gdb_history
set history size 10000
set disassembly-flavor intel
# Rust pretty-printers (path varies by installation)
# python
# import gdb
# gdb.execute('source /path/to/rust-gdb-pretty-printers.py')
# end
Quick Reference Card
+------------------+-------+-------------------------------+
| Action | Short | Full Command |
+------------------+-------+-------------------------------+
| Run | r | run [args] |
| Break | b | break location |
| Continue | c | continue |
| Step over | n | next |
| Step into | s | step |
| Finish function | fin | finish |
| Print variable | p | print expression |
| Examine memory | | x/FMT address |
| Backtrace | bt | backtrace |
| List source | l | list |
| Info breakpoints | i b | info breakpoints |
| Info locals | i lo | info locals |
| Info threads | i th | info threads |
| Quit | q | quit |
+------------------+-------+-------------------------------+