Docs

README

Debugging with GDB

Overview

GDB (GNU Debugger) is a powerful command-line debugger for C/C++ programs. It allows you to inspect program state, set breakpoints, step through code, and find bugs.

Learning Objectives

By the end of this section, you will understand:

  • Starting and running programs in GDB
  • Setting breakpoints and watchpoints
  • Stepping through code
  • Inspecting variables and memory
  • Debugging crashes and core dumps
  • Using GDB with multi-threaded programs

Compilation for Debugging

┌─────────────────────────────────────────────────────────────────────────┐
│                 COMPILE WITH DEBUG SYMBOLS                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Basic compilation with debug symbols                                 │
│  g++ -g program.cpp -o program                                          │
│                                                                         │
│  # Recommended flags for debugging                                      │
│  g++ -g -O0 -Wall -Wextra program.cpp -o program                        │
│                                                                         │
│  # With CMake                                                           │
│  cmake -DCMAKE_BUILD_TYPE=Debug ..                                      │
│                                                                         │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │  -g     : Include debug symbols                                 │    │
│  │  -O0    : Disable optimizations (easier to debug)              │    │
│  │  -ggdb  : Include extra GDB-specific info                      │    │
│  │  -g3    : Maximum debug info (includes macros)                 │    │
│  └────────────────────────────────────────────────────────────────┘    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Starting GDB

┌─────────────────────────────────────────────────────────────────────────┐
│                    STARTING GDB                                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Start GDB with a program                                             │
│  gdb ./program                                                          │
│                                                                         │
│  # Start with arguments                                                 │
│  gdb --args ./program arg1 arg2                                         │
│                                                                         │
│  # Attach to running process                                            │
│  gdb -p <pid>                                                           │
│                                                                         │
│  # Debug a core dump                                                    │
│  gdb ./program core                                                     │
│                                                                         │
│  # Start in TUI mode (text user interface)                              │
│  gdb -tui ./program                                                     │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Essential GDB Commands

Running and Execution

┌─────────────────────────────────────────────────────────────────────────┐
│                    EXECUTION COMMANDS                                    │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  Command              Short   Description                               │
│  ─────────────────────────────────────────────────────────              │
│  run [args]           r       Start program (with optional args)        │
│  continue             c       Continue after breakpoint                  │
│  next                 n       Step over (don't enter functions)         │
│  step                 s       Step into (enter functions)               │
│  finish               fin     Run until current function returns        │
│  until [location]     u       Run until line or location                │
│  kill                         Kill running program                       │
│  quit                 q       Exit GDB                                   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Breakpoints

┌─────────────────────────────────────────────────────────────────────────┐
│                    BREAKPOINT COMMANDS                                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Set breakpoints                                                      │
│  break main                   # At function                             │
│  break file.cpp:42            # At line in file                         │
│  break 42                     # At line in current file                 │
│  break *0x401234              # At address                              │
│                                                                         │
│  # Conditional breakpoints                                              │
│  break 42 if x > 10           # Break only if condition true            │
│                                                                         │
│  # Manage breakpoints                                                   │
│  info breakpoints             # List all breakpoints                    │
│  delete 1                     # Delete breakpoint #1                    │
│  delete                       # Delete all breakpoints                  │
│  disable 1                    # Disable breakpoint #1                   │
│  enable 1                     # Enable breakpoint #1                    │
│                                                                         │
│  # Temporary breakpoint (auto-delete after hit)                         │
│  tbreak main                                                            │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Watchpoints

┌─────────────────────────────────────────────────────────────────────────┐
│                    WATCHPOINTS (Data Breakpoints)                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Break when variable changes                                          │
│  watch x                      # Break when x changes                    │
│  watch *0x601050              # Watch memory address                    │
│                                                                         │
│  # Break when expression becomes true                                   │
│  watch x == 10                                                          │
│                                                                         │
│  # Read watchpoint (break on read)                                      │
│  rwatch x                                                               │
│                                                                         │
│  # Access watchpoint (break on read or write)                           │
│  awatch x                                                               │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Inspecting Variables

┌─────────────────────────────────────────────────────────────────────────┐
│                    INSPECTION COMMANDS                                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Print variables                                                      │
│  print x                  p x     Print variable x                      │
│  print/x x                        Print as hex                          │
│  print/d x                        Print as decimal                      │
│  print/t x                        Print as binary                       │
│  print *ptr                       Print dereferenced pointer            │
│  print arr[0]@10                  Print 10 elements of array            │
│  print (int*)0x601050             Print with cast                       │
│                                                                         │
│  # Display (auto-print on each step)                                    │
│  display x                        Show x after each step                │
│  undisplay 1                      Remove display #1                     │
│  info display                     List displays                         │
│                                                                         │
│  # Examine memory                                                       │
│  x/10xb &var              # 10 bytes in hex                             │
│  x/4xw &var               # 4 words in hex                              │
│  x/s str                  # As string                                   │
│  x/i $pc                  # As instruction                              │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Stack Inspection

┌─────────────────────────────────────────────────────────────────────────┐
│                    STACK COMMANDS                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  backtrace              bt     Show call stack                          │
│  backtrace full         bt f   Stack with local variables               │
│  frame 2                f 2    Select stack frame #2                    │
│  up                            Move up one frame                        │
│  down                          Move down one frame                      │
│  info frame                    Info about current frame                 │
│  info locals                   Show local variables                     │
│  info args                     Show function arguments                  │
│                                                                         │
│  Example backtrace:                                                     │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │  #0  crash_func (x=42) at bug.cpp:10                             │  │
│  │  #1  process (data=0x7fff...) at bug.cpp:25                      │  │
│  │  #2  main (argc=1, argv=0x7fff...) at bug.cpp:40                 │  │
│  └──────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Source Code Navigation

┌─────────────────────────────────────────────────────────────────────────┐
│                    SOURCE CODE COMMANDS                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  list                  l      List source around current line           │
│  list 20                      List around line 20                       │
│  list func                    List function                             │
│  list file.cpp:1              List from file                            │
│  list -                       List previous                             │
│  set listsize 20              Set lines to show                         │
│                                                                         │
│  info source                  Current source file info                  │
│  info sources                 All source files                          │
│  info functions               All functions                             │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Debugging Workflow

┌─────────────────────────────────────────────────────────────────────────┐
│                    TYPICAL DEBUGGING SESSION                             │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│    ┌──────────────────┐                                                 │
│    │   Compile -g     │                                                 │
│    └────────┬─────────┘                                                 │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │   gdb ./program  │                                                 │
│    └────────┬─────────┘                                                 │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │ Set breakpoints  │  break main                                     │
│    └────────┬─────────┘  break suspect_function                         │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │      run         │                                                 │
│    └────────┬─────────┘                                                 │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │ Inspect & step   │  print var, next, step                          │
│    └────────┬─────────┘  backtrace, info locals                         │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │  Find the bug    │                                                 │
│    └────────┬─────────┘                                                 │
│             ▼                                                           │
│    ┌──────────────────┐                                                 │
│    │   Fix & retry    │                                                 │
│    └──────────────────┘                                                 │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Debugging Common Issues

Segmentation Fault

┌─────────────────────────────────────────────────────────────────────────┐
│                    DEBUGGING SEGFAULT                                    │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  $ gdb ./program                                                        │
│  (gdb) run                                                              │
│  Program received signal SIGSEGV, Segmentation fault.                   │
│  0x0000000000401234 in crash_func (ptr=0x0) at bug.cpp:10               │
│                                                                         │
│  (gdb) backtrace                                                        │
│  #0  crash_func (ptr=0x0) at bug.cpp:10                                 │
│  #1  main () at bug.cpp:20                                              │
│                                                                         │
│  (gdb) frame 0                                                          │
│  (gdb) list                                                             │
│  10      return *ptr;    <-- Dereferencing null pointer!                │
│                                                                         │
│  (gdb) print ptr                                                        │
│  $1 = (int *) 0x0                                                       │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Core Dump Analysis

┌─────────────────────────────────────────────────────────────────────────┐
│                    CORE DUMP ANALYSIS                                    │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Enable core dumps                                                    │
│  ulimit -c unlimited                                                    │
│                                                                         │
│  # Run program (crashes and creates core file)                          │
│  ./program                                                              │
│  Segmentation fault (core dumped)                                       │
│                                                                         │
│  # Analyze core dump                                                    │
│  gdb ./program core                                                     │
│  (gdb) backtrace                                                        │
│  (gdb) info registers                                                   │
│  (gdb) x/10i $pc                                                        │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Memory Issues

┌─────────────────────────────────────────────────────────────────────────┐
│                    MEMORY DEBUGGING                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Detect memory leaks with Valgrind                                    │
│  valgrind --leak-check=full ./program                                   │
│                                                                         │
│  # Address Sanitizer (compile-time)                                     │
│  g++ -fsanitize=address -g program.cpp -o program                       │
│  ./program                                                              │
│                                                                         │
│  # GDB memory commands                                                  │
│  (gdb) info proc mappings    # Show memory maps                         │
│  (gdb) x/100xb &buffer       # Examine buffer contents                  │
│  (gdb) find &arr, +1000, 42  # Find value in memory                     │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Multi-threaded Debugging

┌─────────────────────────────────────────────────────────────────────────┐
│                    THREADING COMMANDS                                    │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  info threads                  # List all threads                       │
│  thread 2                      # Switch to thread 2                     │
│  thread apply all bt           # Backtrace all threads                  │
│  thread apply 1-3 print x      # Apply command to threads 1-3           │
│                                                                         │
│  # Set scheduler locking                                                │
│  set scheduler-locking on      # Only current thread runs               │
│  set scheduler-locking step    # Lock during step                       │
│  set scheduler-locking off     # All threads run                        │
│                                                                         │
│  # Break in specific thread                                             │
│  break file.cpp:10 thread 2                                             │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

TUI Mode (Text User Interface)

┌─────────────────────────────────────────────────────────────────────────┐
│                    TUI MODE COMMANDS                                     │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # Start in TUI mode                                                    │
│  gdb -tui ./program                                                     │
│                                                                         │
│  # Toggle TUI in GDB                                                    │
│  Ctrl-x a                      # Toggle TUI                             │
│  Ctrl-x 1                      # One window (source)                    │
│  Ctrl-x 2                      # Two windows (source + asm)             │
│  Ctrl-L                        # Refresh display                        │
│                                                                         │
│  # Layout commands                                                      │
│  layout src                    # Source window                          │
│  layout asm                    # Assembly window                        │
│  layout split                  # Source and assembly                    │
│  layout regs                   # Registers window                       │
│                                                                         │
│  # Focus commands                                                       │
│  focus src                     # Focus on source                        │
│  focus cmd                     # Focus on command line                  │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

GDB Init File

┌─────────────────────────────────────────────────────────────────────────┐
│                    ~/.gdbinit FILE                                       │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  # ~/.gdbinit - Loaded automatically when GDB starts                    │
│                                                                         │
│  # Better display                                                       │
│  set print pretty on                                                    │
│  set print array on                                                     │
│  set print object on                                                    │
│  set print static-members on                                            │
│  set print vtbl on                                                      │
│                                                                         │
│  # History                                                              │
│  set history save on                                                    │
│  set history size 10000                                                 │
│  set history filename ~/.gdb_history                                    │
│                                                                         │
│  # Pagination                                                           │
│  set pagination off                                                     │
│                                                                         │
│  # Custom commands                                                      │
│  define bpl                                                             │
│      info breakpoints                                                   │
│  end                                                                    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Quick Reference

ActionCommand
Start debugginggdb ./program
Run programrun or r
Set breakpointbreak main or b main
Continuecontinue or c
Step overnext or n
Step intostep or s
Print variableprint x or p x
Show backtracebacktrace or bt
List sourcelist or l
Quitquit or q

Next Steps

  • Practice with examples.cpp
  • Complete the exercises.cpp challenges
  • Try debugging real programs with bugs
  • Explore LLDB as an alternative debugger
README - C++ Tutorial | DeepML