A hands-on workshop to learn GDB (GNU Debugger) through practical examples. This workshop covers basic debugging techniques, core dump analysis, and finding multiple bugs in real code.
- A terminal/command line interface
- A C++ compiler (g++ or clang++)
- GDB debugger
brew install gdbAfter installation, you MUST code-sign GDB to use it on macOS. Run:
./install-mac.sh
./codesign-gdb.shImportant: The code signing step is required for GDB to run processes on macOS. Without it, you'll get "Don't know how to run" errors.
sudo port install gdbsudo apt-get update && sudo apt-get install -y gdb g++ build-essentialsudo dnf install -y gdb gcc-c++ makesudo pacman -S gdb gcc makeWe provide automated installation scripts:
macOS:
./install-mac.shLinux:
./install-linux.shLearn fundamental GDB commands:
- Setting breakpoints
- Stepping through code
- Inspecting variables
- Examining the call stack
- Finding off-by-one errors
Bug: Off-by-one error in loop condition (<= instead of <)
Compile:
make demo1Run with GDB:
gdb ./demo1Learn to debug crashes:
- Analyzing segmentation faults
- Examining core dumps
- Understanding null pointer dereferences
- Using
backtraceandframecommands
Bug: Null pointer dereference causing SIGSEGV
Compile:
make demo2Run with GDB:
gdb ./demo2Generate core dump:
ulimit -c unlimited
./demo2
gdb ./demo2 corePut your skills to the test! Find and fix multiple bugs:
- Off-by-one errors
- Division by zero
- Array/vector bounds checking
- Logic errors
Bugs: Multiple issues including:
- Off-by-one in loop
- Division by zero
- Unchecked array index
- Potential memory issues
Compile:
make assignmentRun with GDB:
gdb ./assignment-
Clone this repository:
git clone <repository-url> cd gdb-workshop
-
Install GDB (if not already installed):
# macOS ./install-mac.sh # Linux ./install-linux.sh
-
Compile all programs:
make all
-
Start with Demo 1:
gdb ./demo1
gdb ./program # Start GDB with program
gdb ./program core # Analyze core dump
gdb ./program <pid> # Attach to running processrun [args] # Run the program
start # Start and stop at main
continue (c) # Continue execution
next (n) # Execute next line (step over)
step (s) # Execute next line (step into)
finish # Execute until current function returns
quit (q) # Exit GDB
break (b) <location> # Set breakpoint at location
break main # Break at main function
break file.cpp:42 # Break at line 42 in file.cpp
break function_name # Break at function
info breakpoints # List all breakpoints
delete <num> # Delete breakpoint number
disable <num> # Disable breakpoint
enable <num> # Enable breakpoint
print (p) <variable> # Print variable value
print *ptr # Dereference pointer
print array[0]@10 # Print 10 elements of array
display <variable> # Auto-display variable on each stop
info locals # Show local variables
info args # Show function arguments
backtrace (bt) # Show call stack
frame <num> # Switch to frame number
up # Move up one frame
down # Move down one frame
info frame # Info about current frame
x/<format> <address> # Examine memory
x/10i $pc # Disassemble 10 instructions
info registers # Show all registers
set print pretty on # Pretty print structures
set print array on # Print arrays nicely
set print elements 0 # Print all array elements
set args arg1 arg2 # Set program arguments
show args # Show current arguments
- Set a breakpoint at the
buggy_sumfunction - Run the program with argument
3 - Step through the loop and observe the variable
i - Notice when
iexceeds the vector bounds - Fix the bug and recompile
- Run the program and observe the crash
- Use
backtraceto see where it crashed - Examine the pointer value with
print p - Understand why dereferencing
nullptrcauses SIGSEGV - Fix the bug
- Compile with debug symbols:
g++ -g -o assignment assignment.cpp - Run with different command-line arguments
- Use GDB to find each bug systematically
- Document each bug you find
- Fix all bugs and verify the program works correctly
-
Always compile with debug symbols: Use
-gflagg++ -g -o program program.cpp
-
Use breakpoints strategically: Set breakpoints before suspected bug locations
-
Inspect variables frequently: Use
printanddisplayto watch variables -
Check the call stack: Use
backtraceto understand how you got to the crash -
Read error messages carefully: GDB provides helpful information about crashes
-
Use conditional breakpoints:
break file.cpp:42 if i == 5
If you see these errors on macOS, you need to code-sign GDB. Run:
./codesign-gdb.shThis script will guide you through creating a code signing certificate and signing GDB. This is required due to macOS security restrictions.
Manual code signing (if script doesn't work):
# First, create the certificate in Keychain Access (see codesign-gdb.sh for instructions)
# Then run:
sudo codesign --entitlements gdb-entitlements.xml --force --sign gdb-cert $(which gdb)On Linux, ensure core dumps are enabled:
ulimit -c unlimitedMake sure GDB is in your PATH:
which gdbIf not found, add it to your PATH or use the full path.
This workshop material is provided for educational purposes.