Vai al contenuto

GDB - GNU Debugger

# Ubuntu/Debian installation
sudo apt update
sudo apt install gdb

# Install GDB with additional features
sudo apt install gdb gdb-multiarch

# Install GDB for specific architectures
sudo apt install gdb-arm-linux-gnueabihf
sudo apt install gdb-aarch64-linux-gnu

# CentOS/RHEL/Fedora installation
sudo dnf install gdb
sudo yum install gdb  # Older systems

# macOS installation (using Homebrew)
brew install gdb

# Note: On macOS, you may need to code-sign GDB
# Create a certificate in Keychain Access and sign:
codesign -s gdb-cert /usr/local/bin/gdb

# Windows installation (MinGW/MSYS2)
pacman -S gdb

# Verify installation
gdb --version
gdb --help

# Check supported architectures
gdb --batch --ex "show architecture"

# Check supported languages
gdb --batch --ex "info languages"
```Il GNU Debugger (GDB) si distingue come il debugger più utilizzato e ricco di funzionalità nell'ecosistema Unix e Linux, fungendo da strumento indispensabile per sviluppatori software, amministratori di sistema e ricercatori di sicurezza in tutto il mondo. Originariamente sviluppato come parte del Progetto GNU da Richard Stallman e altri, GDB si è evoluto in oltre tre decenni in una piattaforma di debug sofisticata che supporta molteplici linguaggi di programmazione tra cui C, C++, Ada, Fortran, Go, Rust e molti altri. Il suo set di funzionalità comprende tutto, dal debug di base con breakpoint a capacità avanzate come debug inverso, debug remoto e analisi di applicazioni multi-thread. L'interfaccia a riga di comando di GDB, sebbene inizialmente scoraggiante per i nuovi utenti, fornisce un'energia e flessibilità senza pari per diagnosticare problemi software complessi, rendendolo il debugger di elezione per tutto, dallo sviluppo di sistemi embedded alle applicazioni enterprise su larga scala e al debug del kernel del sistema operativo.

Would you like me to continue with the remaining sections?```bash
# GDB configuration file locations
# System-wide: /etc/gdb/gdbinit
# User-specific: ~/.gdbinit
# Project-specific: .gdbinit (in current directory)

# Sample ~/.gdbinit configuration
cat > ~/.gdbinit << 'EOF'
# Enable history
set history save on
set history size 10000
set history filename ~/.gdb_history

# Pretty printing
set print pretty on
set print array on
set print array-indexes on
set print elements 200

# Disassembly settings
set disassembly-flavor intel
set disassemble-next-line auto

# Auto-load settings
set auto-load safe-path /

# Python support
python
import sys
sys.path.insert(0, '/usr/share/gdb/python')
end

# Convenience variables
set $SHOW_CONTEXT = 1
set $SHOW_NEST_INSN = 0

# Custom commands
define hook-stop
    info registers
    x/5i $pc
end
EOF

# Environment variables
export GDBHISTFILE=~/.gdb_history
export GDBHISTSIZE=10000

# Debugging symbols
# Ensure programs are compiled with debug information
gcc -g -O0 program.c -o program
g++ -g -O0 program.cpp -o program

# Install debug symbols for system libraries (Ubuntu/Debian)
sudo apt install libc6-dbg
sudo apt install libstdc++6-dbg

# Enable core dumps
ulimit -c unlimited
echo "core"|sudo tee /proc/sys/kernel/core_pattern

Basic GDB Usage

Starting and Controlling GDB

# Start GDB with a program
gdb program
gdb ./program
gdb /path/to/program

# Start GDB with arguments
gdb --args program arg1 arg2 arg3

# Attach to running process
gdb -p PID
gdb program PID

# Start GDB in batch mode
gdb --batch --ex "run" --ex "bt" --args program

# Start GDB with core dump
gdb program core
gdb program core.12345

# Remote debugging
gdb -ex "target remote hostname:port" program

# Start program with environment
gdb --ex "set environment VAR=value" program

# Quiet startup (no banner)
gdb -q program
gdb --quiet program

# Execute commands from file
gdb -x commands.gdb program
gdb --command=commands.gdb program

# Basic GDB commands
(gdb) help                    # Show help
(gdb) help running           # Help for specific category
(gdb) help breakpoints       # Help for breakpoints
(gdb) quit                   # Exit GDB
(gdb) q                      # Short form of quit

Running and Controlling Execution

# Run the program
(gdb) run
(gdb) r
(gdb) run arg1 arg2 arg3

# Set program arguments
(gdb) set args arg1 arg2 arg3
(gdb) show args

# Set environment variables
(gdb) set environment VAR=value
(gdb) unset environment VAR
(gdb) show environment

# Set working directory
(gdb) cd /path/to/directory
(gdb) pwd

# Continue execution
(gdb) continue
(gdb) c

# Step execution (into functions)
(gdb) step
(gdb) s
(gdb) step 5                 # Step 5 times

# Next execution (over functions)
(gdb) next
(gdb) n
(gdb) next 3                 # Next 3 times

# Step/next instruction level
(gdb) stepi
(gdb) si
(gdb) nexti
(gdb) ni

# Finish current function
(gdb) finish
(gdb) fin

# Until (run until line or address)
(gdb) until
(gdb) until 25               # Until line 25
(gdb) until function_name

# Jump to location
(gdb) jump 25                # Jump to line 25
(gdb) jump *0x400123         # Jump to address

# Return from function
(gdb) return
(gdb) return 42              # Return with value

Breakpoints and Watchpoints

Setting Breakpoints

# Set breakpoint at function
(gdb) break main
(gdb) b main
(gdb) break function_name

# Set breakpoint at line number
(gdb) break 25
(gdb) b 25
(gdb) break file.c:25

# Set breakpoint at address
(gdb) break *0x400123
(gdb) b *main+10

# Conditional breakpoints
(gdb) break main if argc > 1
(gdb) break 25 if x == 5
(gdb) break function if strcmp(str, "test") == 0

# Temporary breakpoints (delete after hit)
(gdb) tbreak main
(gdb) tb 25

# Set breakpoint with commands
(gdb) break main
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>print "Entering main"
>print argc
>continue
>end

# Breakpoint on system calls
(gdb) catch syscall
(gdb) catch syscall write
(gdb) catch syscall 1        # sys_exit

# Breakpoint on signals
(gdb) catch signal SIGSEGV
(gdb) catch signal SIGINT

# Breakpoint on C++ exceptions
(gdb) catch throw
(gdb) catch catch
(gdb) catch exception std::runtime_error

Managing Breakpoints

# List breakpoints
(gdb) info breakpoints
(gdb) info b

# Enable/disable breakpoints
(gdb) disable 1              # Disable breakpoint 1
(gdb) enable 1               # Enable breakpoint 1
(gdb) disable                # Disable all breakpoints
(gdb) enable                 # Enable all breakpoints

# Delete breakpoints
(gdb) delete 1               # Delete breakpoint 1
(gdb) delete 1-3             # Delete breakpoints 1-3
(gdb) delete                 # Delete all breakpoints
(gdb) clear                  # Clear breakpoint at current location
(gdb) clear main             # Clear breakpoint at main
(gdb) clear 25               # Clear breakpoint at line 25

# Modify breakpoint conditions
(gdb) condition 1 x > 10     # Add condition to breakpoint 1
(gdb) condition 1            # Remove condition from breakpoint 1

# Ignore breakpoint hits
(gdb) ignore 1 5             # Ignore next 5 hits of breakpoint 1

# Save and restore breakpoints
(gdb) save breakpoints file.bp
(gdb) source file.bp

Watchpoints

# Watch variable for changes
(gdb) watch variable
(gdb) watch *0x400123        # Watch memory address

# Read watchpoint (break when read)
(gdb) rwatch variable
(gdb) rwatch *0x400123

# Access watchpoint (break on read or write)
(gdb) awatch variable
(gdb) awatch *0x400123

# Conditional watchpoints
(gdb) watch x if x > 100

# Watch expressions
(gdb) watch (x + y)
(gdb) watch strlen(str)

# Hardware vs software watchpoints
(gdb) set can-use-hw-watchpoints 0  # Force software watchpoints
(gdb) set can-use-hw-watchpoints 1  # Allow hardware watchpoints

# List watchpoints
(gdb) info watchpoints

Examining Program State

Stack and Frames

# Show stack trace (backtrace)
(gdb) backtrace
(gdb) bt
(gdb) bt full                # Show local variables
(gdb) bt 10                  # Show only 10 frames

# Navigate stack frames
(gdb) frame 0                # Go to frame 0 (current)
(gdb) frame 2                # Go to frame 2
(gdb) up                     # Go up one frame
(gdb) down                   # Go down one frame
(gdb) up 2                   # Go up 2 frames

# Show current frame
(gdb) frame
(gdb) f

# Show frame information
(gdb) info frame
(gdb) info args              # Show function arguments
(gdb) info locals            # Show local variables
(gdb) info registers         # Show CPU registers
(gdb) info all-registers     # Show all registers including FPU

# Select frame and examine
(gdb) frame 1
(gdb) list                   # Show source code
(gdb) print variable         # Print variable in this frame

Variables and Memory

# Print variables
(gdb) print variable
(gdb) p variable
(gdb) print/x variable       # Print in hexadecimal
(gdb) print/d variable       # Print in decimal
(gdb) print/o variable       # Print in octal
(gdb) print/t variable       # Print in binary
(gdb) print/c variable       # Print as character
(gdb) print/f variable       # Print as float

# Print arrays
(gdb) print array[0]@10      # Print first 10 elements
(gdb) print *array@10        # Same as above
(gdb) print array            # Print entire array (if size known)

# Print structures
(gdb) print struct_var
(gdb) print struct_var.member
(gdb) print/x struct_var     # Print in hex

# Print pointers
(gdb) print pointer
(gdb) print *pointer         # Dereference pointer
(gdb) print pointer[5]       # Array notation

# Examine memory
(gdb) x/10x 0x400123         # Examine 10 hex words at address
(gdb) x/10i $pc              # Examine 10 instructions at PC
(gdb) x/s 0x400123           # Examine string at address
(gdb) x/10c 0x400123         # Examine 10 characters

# Memory examination formats
# x/[count][format][size] address
# count: number of units to display
# format: x(hex), d(decimal), u(unsigned), o(octal), t(binary),
#         a(address), c(char), f(float), s(string), i(instruction)
# size: b(byte), h(halfword), w(word), g(giant/8bytes)

(gdb) x/10xb 0x400123        # 10 bytes in hex
(gdb) x/5xw 0x400123         # 5 words in hex
(gdb) x/20i main             # 20 instructions starting at main

Registers and Assembly

# Show registers
(gdb) info registers
(gdb) info reg
(gdb) info registers rax rbx # Show specific registers

# Show all registers including floating point
(gdb) info all-registers

# Print specific register
(gdb) print $rax
(gdb) print/x $rip
(gdb) print $pc              # Program counter

# Set register value
(gdb) set $rax = 0x12345678

# Disassemble
(gdb) disassemble
(gdb) disas
(gdb) disassemble main       # Disassemble function
(gdb) disassemble 0x400123   # Disassemble at address
(gdb) disas main,+50         # Disassemble 50 bytes from main
(gdb) disas $pc-10,$pc+10    # Disassemble around PC

# Set disassembly flavor
(gdb) set disassembly-flavor intel
(gdb) set disassembly-flavor att

# Show next instruction
(gdb) display/i $pc
(gdb) x/i $pc

# Step by instruction
(gdb) stepi
(gdb) si
(gdb) nexti
(gdb) ni

Advanced Debugging Features

Multi-threaded Debugging

# Show threads
(gdb) info threads

# Switch to thread
(gdb) thread 2               # Switch to thread 2
(gdb) thread apply all bt    # Show backtrace for all threads
(gdb) thread apply 1-3 print variable  # Apply command to threads 1-3

# Thread-specific breakpoints
(gdb) break main thread 2    # Break in main only for thread 2
(gdb) break main thread 2 if x > 5

# Control thread execution
(gdb) set scheduler-locking on   # Only current thread runs
(gdb) set scheduler-locking off  # All threads run
(gdb) set scheduler-locking step # Only current thread steps

# Show thread-local storage
(gdb) info address variable

# Non-stop mode (continue other threads while debugging one)
(gdb) set non-stop on
(gdb) set target-async on

Remote Debugging

# Start gdbserver on target machine
gdbserver :1234 program
gdbserver localhost:1234 program arg1 arg2

# Attach gdbserver to running process
gdbserver :1234 --attach PID

# Connect from GDB
(gdb) target remote hostname:1234
(gdb) target remote 192.168.1.100:1234

# Extended remote debugging
(gdb) target extended-remote hostname:1234
(gdb) set remote exec-file /path/to/program
(gdb) run

# File transfer
(gdb) remote put localfile remotefile
(gdb) remote get remotefile localfile

# Monitor commands
(gdb) monitor help           # Show gdbserver commands
(gdb) monitor exit           # Exit gdbserver

Core Dump Analysis

# Generate core dump
ulimit -c unlimited          # Enable core dumps
kill -SEGV PID              # Force segmentation fault

# Load core dump
gdb program core
gdb program core.12345

# Analyze core dump
(gdb) bt                     # Show stack trace
(gdb) info registers         # Show register state
(gdb) print variable         # Examine variables
(gdb) x/10i $pc             # Show instructions around crash

# Generate core dump from running process
(gdb) generate-core-file
(gdb) gcore                  # Same as above

# Core dump with specific name
(gdb) generate-core-file mycore.dump

Reverse Debugging

# Enable recording (required for reverse debugging)
(gdb) record
(gdb) record full            # Full recording mode

# Reverse execution commands
(gdb) reverse-continue       # Continue backwards
(gdb) rc                     # Short form
(gdb) reverse-step           # Step backwards
(gdb) rs
(gdb) reverse-next           # Next backwards
(gdb) rn
(gdb) reverse-stepi          # Step instruction backwards
(gdb) rsi
(gdb) reverse-nexti          # Next instruction backwards
(gdb) rni

# Reverse finish
(gdb) reverse-finish         # Reverse until function entry

# Set reverse breakpoints
(gdb) break main
(gdb) reverse-continue       # Will stop at previous hit

# Recording information
(gdb) info record
(gdb) record stop            # Stop recording
(gdb) record save filename   # Save recording to file
(gdb) record restore filename # Restore recording from file

Scripting and Automation

GDB Commands and Scripts

# Define custom commands
(gdb) define mycommand
Type commands for definition of "mycommand".
End with a line saying just "end".
>print "Custom command executed"
>info registers
>end

# Command with arguments
(gdb) define print_array
Type commands for definition of "print_array".
End with a line saying just "end".
>print *$arg0@$arg1
>end
# Usage: print_array array 10

# Conditional commands
(gdb) define check_value
>if $arg0 > 100
>  print "Value is large"
>else
>  print "Value is small"
>end
>end

# Loop commands
(gdb) define print_range
>set $i = $arg0
>while $i <= $arg1
>  print $i
>  set $i = $i + 1
>end
>end

# Save commands to file
(gdb) set logging file commands.gdb
(gdb) set logging on
(gdb) show commands
(gdb) set logging off

# Execute commands from file
(gdb) source commands.gdb

Python Scripting

# Enable Python in GDB
(gdb) python print("Hello from Python")

# Python script example
(gdb) python
>import gdb
>class MyCommand(gdb.Command):
>    def __init__(self):
>        super().__init__("mypy", gdb.COMMAND_USER)
>    def invoke(self, arg, from_tty):
>        print(f"Argument: \\\\{arg\\\\}")
>        frame = gdb.selected_frame()
>        print(f"Function: \\\\{frame.name()\\\\}")
>MyCommand()
>end

# Load Python script
(gdb) source script.py

# Python pretty printers
(gdb) python
>import gdb.printing
>class MyPrinter:
>    def __init__(self, val):
>        self.val = val
>    def to_string(self):
>        return f"MyStruct(\\\\{self.val['x']\\\\}, \\\\{self.val['y']\\\\})"
>def my_printer_lookup(val):
>    if str(val.type) == "struct MyStruct":
>        return MyPrinter(val)
>    return None
>gdb.printing.register_pretty_printer(None, my_printer_lookup)
>end

# Convenience functions in Python
(gdb) python
>class MyFunction(gdb.Function):
>    def __init__(self):
>        super().__init__("myfunc")
>    def invoke(self, arg):
>        return int(arg) * 2
>MyFunction()
>end
# Usage: print $myfunc(5)

Debugging Automation

# Automatic commands on breakpoint
(gdb) break main
(gdb) commands 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>printf "main called with argc=%d\n", argc
>continue
>end

# Hook commands (execute before/after other commands)
(gdb) define hook-stop
>info registers
>x/5i $pc
>end

(gdb) define hookpost-step
>print "Step completed"
>end

# Batch mode execution
gdb --batch \
    --ex "file program" \
    --ex "break main" \
    --ex "run" \
    --ex "bt" \
    --ex "quit"

# Automated testing script
cat > test_debug.gdb << 'EOF'
file program
break main
run arg1 arg2
print argc
print argv[0]
continue
break function_name
continue
print local_var
bt
quit
EOF

gdb -x test_debug.gdb

Specialized Debugging

Memory Debugging

# Detect memory corruption
(gdb) set environment MALLOC_CHECK_=2

# Use AddressSanitizer with GDB
# Compile with: gcc -g -fsanitize=address program.c
(gdb) set environment ASAN_OPTIONS=abort_on_error=1

# Memory mapping information
(gdb) info proc mappings
(gdb) info files

# Heap analysis
(gdb) info heap              # If available
(gdb) heap                   # Custom command if defined

# Memory leak detection
(gdb) set environment MALLOC_TRACE=mtrace.log
# After program execution:
# mtrace program mtrace.log

Kernel Debugging

# Kernel debugging with QEMU
qemu-system-x86_64 -kernel bzImage -s -S

# Connect GDB to kernel
(gdb) target remote :1234
(gdb) symbol-file vmlinux

# Load kernel modules
(gdb) add-symbol-file module.ko 0xaddress

# Kernel-specific commands
(gdb) info threads           # Show kernel threads
(gdb) thread apply all bt    # Backtrace all threads

# KGDB (kernel debugger)
# Enable in kernel config: CONFIG_KGDB=y
# Boot with: kgdboc=ttyS0,115200 kgdbwait

Debug dei Sistemi Embedded

# OpenOCD integration
# Start OpenOCD with appropriate config
openocd -f board/stm32f4discovery.cfg

# Connect GDB to OpenOCD
(gdb) target remote :3333
(gdb) monitor reset halt
(gdb) load                   # Load program to target
(gdb) monitor reset init

# ARM-specific commands
(gdb) info registers         # Show ARM registers
(gdb) info all-registers     # Include system registers

# Flash programming
(gdb) monitor flash write_image erase program.elf
(gdb) monitor flash verify_image program.elf

# Real-time debugging
(gdb) monitor poll off       # Disable polling
(gdb) monitor poll on        # Enable polling

L'ampio set di funzionalità e l'estensibilità di GDB lo rendono uno strumento indispensabile per lo sviluppo software e il debugging su una vasta gamma di piattaforme e applicazioni. Dalla semplice debug di programmi ad applicazioni multi-thread complesse, sviluppo di kernel e sistemi embedded, GDB offre la profondità e la flessibilità necessarie per diagnosticare e risolvere anche i problemi software più impegnativi. La sua interfaccia a riga di comando, pur richiedendo una curva di apprendimento, offre una potenza e precisione ineguagliabili per gli sviluppatori che investono tempo per padroneggiare le sue capacità.