GDB Debugger

GDB cheatsheet — set breakpoints, step through code, inspect variables, debug crashes. break, run, next, step, print, backtrace, watch. Full GNU debugger reference.

12 min read

What it is

GDB is the GNU Debugger, a powerful command-line tool for inspecting and controlling the execution of programs to find and fix bugs. You reach for GDB when you need to step through code, examine variables, set breakpoints, and understand program flow at runtime.

Installation

Linux

sudo apt update && sudo apt install gdb
# or
sudo yum install gdb

macOS

GDB is not installed by default on macOS. You can install it using Homebrew:

brew install gdb

Note: On macOS, you’ll need to sign GDB for debugging. After installation, run:

codesign --entitlements /tmp/entitlements.xml -s gdb_codesign_identity /path/to/your/gdb/executable

You’ll first need to create /tmp/entitlements.xml with content like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>com.apple.security.get-task-allow</key>
  <true/>
</dict>
</plist>

And then create a codesign identity:

sudo security create-generic-password -a $(whoami) -s gdb_codesign_identity -l "gdb-entitlement"

Finally, you’ll need to allow the signed GDB executable to run.

Windows

GDB is typically installed as part of the MinGW-w64 distribution. Download and install MinGW-w64 from mingw-w64.org. Ensure the gdb package is selected during installation. The executable will be available in the MinGW’s bin directory.

Core Concepts

  • Inferior Process: The program you are debugging.
  • Breakpoints: Points in your code where you tell GDB to stop execution.
  • Stepping: Executing code line by line or function by function.
  • Stack Trace: A list of active function calls at a given point in execution, showing the call history.
  • Frame: A single function call on the stack, containing local variables and arguments.
  • Watchpoints: Breakpoints that trigger when the value of a specific variable or memory location changes.
  • Symbols: Information about functions, variables, and types in your program, usually generated by the compiler with debugging flags (e.g., -g).

Commands / Usage

Starting GDB

  • Start GDB with a program:

    gdb ./my_program
    

    Starts GDB and loads my_program without running it yet.

  • Start GDB and run with arguments:

    gdb ./my_program arg1 arg2
    

    Starts GDB, loads my_program, and prepares to run it with arg1 and arg2 as command-line arguments.

  • Attach to a running process:

    gdb -p 12345
    

    Attaches GDB to the process with PID 12345.

  • Start GDB and load core dump:

    gdb ./my_program core.12345
    

    Loads the core dump core.12345 from the crashed my_program for post-mortem debugging.

Running and Controlling Execution

  • Run the program:

    (gdb) run
    

    Starts execution of the loaded program. If arguments were specified during gdb startup, they are used.

  • Run with new arguments:

    (gdb) run arg3 arg4
    

    Restarts the program with the new command-line arguments arg3 and arg4.

  • Continue execution:

    (gdb) continue
    

    Resumes execution until the next breakpoint, signal, or program termination.

  • Continue with a count:

    (gdb) continue 5
    

    Continues execution, stopping at the 5th breakpoint encountered.

  • Step to the next line:

    (gdb) next
    

    Executes the current line and stops at the next line in the current source file. If the current line is a function call, next executes the function entirely and stops after it returns.

  • Step into a function:

    (gdb) step
    

    Executes the current line. If the current line is a function call, step stops at the first line inside that function.

  • Step until a specific line:

    (gdb) next-line 25
    

    Executes lines until line 25 in the current file is reached.

  • Step until a specific function:

    (gdb) step-at my_function
    

    Executes until the first line of my_function is reached.

  • Step until return:

    (gdb) finish
    

    Continues execution until the current function returns, then stops.

  • Continue until a specific line:

    (gdb) until 42
    

    Continues execution until line 42 in the current file is reached.

  • Interrupt execution:

    (gdb) interrupt
    

    Stops the running program. Equivalent to pressing Ctrl+C in the terminal where GDB is running.

  • Kill the inferior process:

    (gdb) kill
    

    Terminates the program being debugged.

Breakpoints

  • Set a breakpoint at a line number:

    (gdb) break 15
    

    Sets a breakpoint at line 15 in the current source file.

  • Set a breakpoint at a function name:

    (gdb) break my_function
    

    Sets a breakpoint at the first line of the function my_function.

  • Set a breakpoint at a specific file and line:

    (gdb) break main.c:20
    

    Sets a breakpoint at line 20 in main.c.

  • Set a breakpoint with a condition:

    (gdb) break my_function if i == 10
    

    Sets a breakpoint at my_function that only stops when the variable i is equal to 10.

  • Set a breakpoint that runs a command:

    (gdb) break my_function commands
    > silent  # Don't print "Breakpoint hit" message
    > printf "Value of x: %d\n", x
    > continue
    > end
    

    Sets a breakpoint that silently prints the value of x and then continues execution.

  • Set a watchpoint for a variable:

    (gdb) watch my_variable
    

    Stops execution whenever the value of my_variable changes.

  • Set a watchpoint for an expression:

    (gdb) watch *ptr
    

    Stops execution whenever the memory location pointed to by ptr changes.

  • Set a hardware watchpoint:

    (gdb) awatch my_variable
    

    Stops when my_variable is accessed (read or written).

  • Set a watchpoint for write access:

    (gdb) rwatch my_variable
    

    Stops when my_variable is read.

  • List all breakpoints:

    (gdb) info breakpoints
    

    Displays a numbered list of all breakpoints, watchpoints, and catchpoints.

  • Delete a breakpoint:

    (gdb) delete 1
    

    Deletes breakpoint number 1.

  • Disable a breakpoint:

    (gdb) disable 1
    

    Temporarily disables breakpoint number 1.

  • Enable a breakpoint:

    (gdb) enable 1
    

    Re-enables a disabled breakpoint number 1.

  • Clear breakpoints in a file/function:

    (gdb) clear main.c:20
    

    Removes breakpoints at line 20 in main.c.

  • Clear all breakpoints:

    (gdb) clear
    

    Removes all breakpoints.

Inspecting Data

  • Print a variable’s value:

    (gdb) print my_variable
    

    Displays the current value of my_variable.

  • Print an expression’s value:

    (gdb) print my_variable * 2 + 5
    

    Evaluates and prints the result of the expression.

  • Print a pointer’s value (address):

    (gdb) print &my_variable
    

    Prints the memory address of my_variable.

  • Print the value at a memory address:

    (gdb) print *0x7fffffffdc88
    

    Prints the value stored at the specified memory address.

  • Print a variable in hexadecimal:

    (gdb) print/x my_variable
    

    Prints my_variable in hexadecimal format.

  • Print a variable in decimal:

    (gdb) print/d my_variable
    

    Prints my_variable in decimal format.

  • Print a variable in character format:

    (gdb) print/c my_variable
    

    Prints my_variable as a character.

  • Print a variable as a string:

    (gdb) print/s my_string_pointer
    

    Prints the null-terminated string pointed to by my_string_pointer.

  • Display a variable automatically:

    (gdb) display my_variable
    

    Prints my_variable’s value every time the program stops.

  • Undisplay a variable:

    (gdb) undisplay 1
    

    Stops automatically displaying the variable associated with display number 1.

  • List displayed variables:

    (gdb) info display
    

    Shows all variables that are set to be displayed automatically.

  • Examine memory:

    (gdb) x/10xw 0x7fffffffdc88
    

    Examines 10 words (x) in hexadecimal (x) format starting at memory address 0x7fffffffdc88. Format specifiers:

    • x: hexadecimal
    • d: decimal
    • u: unsigned decimal
    • o: octal
    • t: binary
    • a: address
    • i: instruction
    • c: character
    • f: float
    • s: string Size specifiers:
    • b: byte (8 bits)
    • h: halfword (16 bits)
    • w: word (32 bits)
    • g: giant word (64 bits) Count: number of units to display.

Stack and Frames

  • Backtrace (show call stack):

    (gdb) backtrace
    

    Prints a list of all function calls that led to the current point of execution.

  • Backtrace with frame numbers:

    (gdb) bt
    

    Shorthand for backtrace.

  • Backtrace with more output:

    (gdb) backtrace full
    

    Prints the call stack and the local variables for each frame.

  • Select a stack frame:

    (gdb) frame 2
    

    Selects frame number 2 from the backtrace. You can then examine variables and source code in that frame’s context.

  • Select a frame by function name:

    (gdb) frame my_function
    

    Selects the most recent frame associated with my_function.

  • Up one stack frame:

    (gdb) up
    

    Moves the current frame selection one level up the call stack.

  • Down one stack frame:

    (gdb) down
    

    Moves the current frame selection one level down the call stack.

  • List local variables in the current frame:

    (gdb) info locals
    
  • List function arguments in the current frame:

    (gdb) info args
    
  • List all symbols in the current frame:

    (gdb) info locals
    (gdb) info args
    

Source Code Navigation

  • List source code around the current line:

    (gdb) list
    

    Shows 10 lines of source code centered around the current execution point.

  • List source code around a specific line:

    (gdb) list 30
    

    Shows 10 lines of source code centered around line 30.

  • List source code for a specific function:

    (gdb) list my_function
    

    Shows the source code for my_function.

  • List source code for a file and line:

    (gdb) list main.c:50
    

    Shows source code around line 50 in main.c.

  • Set the current line:

    (gdb) set line-number 25
    

    Changes the current line number to 25 without executing any code.

  • Set the current file:

    (gdb) set filename my_other_file.c
    

    Changes the current source file.

Program Information

  • Show current file and line number:

    (gdb) info line
    
  • Show program status:

    (gdb) info program
    
  • Show loaded shared libraries:

    (gdb) info sharedlibrary
    
  • Show threads:

    (gdb) info threads
    
  • Select a thread:

    (gdb) thread 2
    

Exiting GDB

  • Quit GDB:

    (gdb) quit
    

    Exits the GDB debugger.

  • Quit without saving history:

    (gdb) quit -n
    

Scripting and Configuration

  • Source a GDB script file:

    (gdb) source my_script.gdb
    

    Executes commands from my_script.gdb.

  • Set a GDB init file:

    gdb -x ~/.gdbinit ./my_program
    

    Runs GDB with commands from ~/.gdbinit.

  • Set a GDB command:

    (gdb) set variable my_var = 10
    

    Assigns a value to a variable.

  • Set an environment variable:

    (gdb) set env MY_VAR=some_value
    
  • Show environment variables:

    (gdb) show env
    

Assembly Level Debugging

  • Disassemble a function:

    (gdb) disassemble my_function
    

    Shows the assembly code for my_function.

  • Disassemble current function:

    (gdb) disassemble
    
  • Disassemble memory region:

    (gdb) disassemble $pc, +50
    

    Disassembles 50 bytes starting from the program counter ($pc).

  • Set instruction pointer:

    (gdb) set $pc = 0x400500
    

    Manually sets the instruction pointer to a specific address.

Other Useful Commands

  • Help:

    (gdb) help
    

    Shows a list of available help topics.

  • Help on a specific command:

    (gdb) help print
    

    Shows detailed help for the print command.

  • Set output radix (number base):

    (gdb) set radix 16
    

    Sets the default number base for printing to hexadecimal.

  • Show output radix:

    (gdb) show radix
    
  • Set disassembly flavor:

    (gdb) set disassembly-flavor intel
    

    Sets the assembly syntax to Intel style (default is AT&T).

  • Set disassembly flavor:

    (gdb) set disassembly-flavor att
    

    Sets the assembly syntax to AT&T style.

Common Patterns

  • Debugging a crash (core dump):

    gdb ./your_program core_file
    (gdb) bt
    (gdb) frame <frame_number>
    (gdb) info locals
    (gdb) print <variable>
    

    Analyze the state of the program at the time of the crash.

  • Finding a memory leak (using Valgrind, then GDB): Run your program with Valgrind first to identify potential leaks. Then, use GDB to step through the code paths that Valgrind indicates are problematic.

    valgrind --leak-check=full ./your_program
    gdb ./your_program
    (gdb) run
    # ... step through code ...
    (gdb) break <line_number>
    (gdb) continue
    
  • Debugging a specific function:

    gdb ./your_program
    (gdb) break my_function
    (gdb) run
    # Program stops at the beginning of my_function
    (gdb) next  # Step through lines
    (gdb) step  # Step into functions
    (gdb) print my_variable
    
  • Watching a variable change:

    gdb ./your_program
    (gdb) watch my_changing_variable
    (gdb) run
    # Program stops when my_changing_variable's value changes
    (gdb) backtrace
    
  • Debugging a race condition (using thread breakpoints):

    gdb ./your_program
    (gdb) break my_thread_function
    (gdb) set a breakpoint condition for specific threads if needed
    (gdb) run
    # ... inspect threads ...
    (gdb) info threads
    (gdb) thread <thread_id>
    (gdb) backtrace
    
  • Conditional breakpoint for debugging a loop:

    gdb ./your_program
    (gdb) break my_loop_function if loop_counter == 1000
    (gdb) run
    # Program stops when loop_counter reaches 1000
    
  • Debugging with a .gdbinit file for common settings: Create ~/.gdbinit with content like:

    set disassembly-flavor intel
    set print pretty on
    set print array on
    

    Then simply run:

    gdb ./your_program
    

Gotchas

  • No Symbols (-g flag): If your program was compiled without debugging symbols (e.g., without -g), GDB will have very limited information. You won’t see source code, function names, or variable names, making debugging extremely difficult.

    # Compile with debugging symbols
    gcc -g my_program.c -o my_program
    
  • Optimized Code: Compilers often optimize code, which can rearrange instructions, remove variables, or inline functions. This makes debugging harder as the execution flow in GDB might not match the source code line-by-line. Compile with -O0 for less optimization during debugging.

    gcc -g -O0 my_program.c -o my_program
    
  • Attach Permissions (Linux): On Linux, you often need root privileges or specific ptrace_scope settings to attach GDB to a running process.

    # To allow non-root users to attach to any process (use with caution)
    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    
  • macOS Code Signing: As mentioned in installation, GDB on macOS requires special code signing to attach to processes. Forgetting this step will prevent GDB from working correctly.

  • Watchpoint Limitations: Hardware watchpoints are limited by the number of available hardware watchpoint registers on the CPU. If you set too many, GDB might fall back to software watchpoints, which are much slower.

  • Signal Handling: GDB intercepts signals by default. If you want the program to handle signals itself, you need to tell GDB not to catch them.

    (gdb) info signals
    # Shows which signals GDB is handling
    (gdb) handle SIGSEGV nostop noprint pass
    # Tells GDB not to stop for SIGSEGV, not to print a message, and to pass it to the program.
    
  • print vs display: print shows the value once. display shows the value every time the program stops. Forgetting to undisplay a variable can lead to a lot of output.

  • Floating Point Precision: Printing floating-point numbers might show fewer digits than you expect due to default precision settings.

    (gdb) set print float-precision 10
    

    Sets the precision for printing floating-point numbers.