Per utilizzare GDB il programma va compilato con simboli di debug (-g). Opzionalmente disabilitare le ottimizzazioni (-O0) per un'esperienza di debug più prevedibile.
# Compilazione con debug symbols gcc -g -O0 main.c -o prog # Con DWARF-4 (massimo dettaglio) gcc -g3 -gdwarf-4 -O0 main.c -o prog # C++ con debug g++ -g -O0 -std=c++17 main.cpp -o prog # Multifile con Makefile: aggiungere -g a CFLAGS CFLAGS = -g -O0 -Wall
| Comando | Descrizione |
|---|---|
gdb prog | Avvia GDB con eseguibile prog |
gdb -q prog | Avvio silenzioso (no banner) |
gdb --args prog arg1 arg2 | Avvia con argomenti da passare al programma |
gdb -p PID | Attach a un processo già in esecuzione |
gdb prog core | Analizza un core dump |
gdb -tui prog | Avvia in modalità TUI (interfaccia testuale) |
gdb -x script.gdb prog | Esegui comandi da file all'avvio |
gdb -batch -x cmds.gdb prog | Esegui in batch mode (non interattivo) |
| Comando | Abbreviazione | Descrizione |
|---|---|---|
quit | q | Esci da GDB |
help <cmd> | h | Aiuto su un comando |
apropos <keyword> | Cerca comandi per keyword | |
shell <cmd> | Esegui un comando shell senza uscire | |
!ls | Scorciatoia per shell ls | |
set pagination off | Disabilita il paging dell'output | |
set confirm off | Non chiedere conferma per quit/kill |
| Comando | Abbreviazione | Descrizione |
|---|---|---|
run | r | Avvia (o riavvia) il programma |
run arg1 arg2 | r arg1 arg2 | Avvia con argomenti (argc/argv) |
run < input.txt | Avvia con stdin da file | |
run > out.txt 2>&1 | Redirect stdout/stderr | |
start | Avvia e si ferma all'inizio di main() | |
starti | Avvia e si ferma alla prima istruzione (entry point) | |
continue | c | Riprendi esecuzione fino al prossimo breakpoint |
continue N | c N | Ignora i prossimi N breakpoint, poi fermati |
kill | k | Termina il programma in debug |
(gdb) set args --verbose file.txt 42 (gdb) show args Argument list to give program being debugged: "--verbose file.txt 42" # Equivale a lanciare: ./prog --verbose file.txt 42 # argc = 4, argv[0]="./prog", argv[1]="--verbose", argv[2]="file.txt", argv[3]="42" (gdb) run # usa gli args impostati (gdb) run --other # override: usa questi invece
(gdb) set environment LANG = it_IT.UTF-8 (gdb) unset environment LD_PRELOAD (gdb) show environment PATH
# Attach a processo esistente (gdb) attach 12345 (gdb) detach # rilascia il processo # Da riga di comando gdb -p 12345
I breakpoints fermano l'esecuzione in un punto specifico. Ogni breakpoint ha un numero identificativo.
| Comando | Descrizione |
|---|---|
break main | Break all'inizio di main() |
break 42 | Break alla riga 42 del file corrente |
break file.c:42 | Break alla riga 42 di file.c |
break func | Break all'inizio della funzione func |
break file.c:func | Break alla funzione func in file.c |
break *0x4005a0 | Break a indirizzo esadecimale (utile per assembly) |
break +5 | Break 5 righe dopo la posizione corrente |
break -3 | Break 3 righe prima della posizione corrente |
tbreak main | Breakpoint temporaneo (si cancella dopo il primo hit) |
rbreak regex | Break su tutte le funzioni che matchano la regex |
# Break solo se la condizione è vera (gdb) break 42 if i == 10 (gdb) break func if strcmp(name, "test") == 0 (gdb) break loop.c:50 if ptr != 0 && ptr->count > 100 # Aggiungere condizione a un breakpoint esistente (gdb) condition 3 x > 0 # bp #3 si attiva solo se x > 0 (gdb) condition 3 # rimuovi la condizione dal bp #3
| Comando | Descrizione |
|---|---|
info breakpoints | Lista tutti i breakpoints (alias i b) |
delete 3 | Elimina breakpoint #3 |
delete | Elimina tutti i breakpoints |
disable 3 | Disabilita bp #3 (senza eliminarlo) |
enable 3 | Riabilita bp #3 |
enable once 3 | Abilita bp #3 solo per un hit, poi disabilita |
enable delete 3 | Abilita bp #3, lo elimina dopo il primo hit |
ignore 3 10 | Ignora bp #3 per i prossimi 10 hit |
clear func | Rimuovi breakpoint alla funzione func |
clear 42 | Rimuovi breakpoint alla riga 42 |
(gdb) save breakpoints bp.txt # salva tutti i bp su file (gdb) source bp.txt # ricarica i bp da file
I watchpoints fermano l'esecuzione quando il valore di un'espressione cambia (o viene letto/scritto).
| Comando | Descrizione |
|---|---|
watch x | Ferma quando x viene modificata (write) |
watch *0x601040 | Watch su indirizzo di memoria |
watch arr[5] | Watch su elemento specifico di un array |
watch ptr->field | Watch su campo di una struct via puntatore |
watch -l ptr->field | Watch sulla locazione di memoria (non sull'espressione) |
rwatch x | Ferma quando x viene letta (read) |
awatch x | Ferma su qualsiasi accesso (read o write) |
watch x if x > 100 | Watchpoint condizionale |
info watchpoints | Lista watchpoints attivi |
| Comando | Abbr. | Descrizione |
|---|---|---|
next | n | Step over — esegui la prossima riga, senza entrare nelle funzioni |
next N | n N | Esegui N righe (step over) |
step | s | Step into — entra nella funzione chiamata |
step N | s N | Esegui N step into |
finish | fin | Step out — esegui fino al return della funzione corrente |
until | u | Esegui fino a superare la riga corrente (utile nei loop) |
until 60 | u 60 | Esegui fino alla riga 60 |
advance func | Continua fino a raggiungere func (come tbreak + continue) | |
jump 50 | j 50 | Salta alla riga 50 (attenzione: non esegue le righe saltate!) |
jump *0x4005a0 | Salta a un indirizzo specifico |
| Comando | Abbr. | Descrizione |
|---|---|---|
nexti | ni | Step over una singola istruzione macchina |
stepi | si | Step into una singola istruzione macchina |
nexti 5 | ni 5 | Esegui 5 istruzioni macchina (step over) |
jump è pericoloso: salta senza eseguire le righe intermedie. Le variabili locali potrebbero essere in stato inconsistente. Usare con cautela!| Comando | Descrizione |
|---|---|
print x | Stampa il valore della variabile x |
print/x x | Stampa in esadecimale |
print/d x | Stampa in decimale (con segno) |
print/u x | Stampa in decimale (senza segno) |
print/o x | Stampa in ottale |
print/t x | Stampa in binario |
print/c x | Stampa come carattere |
print/f x | Stampa come float |
print/a x | Stampa come indirizzo (con simbolo più vicino) |
print/s ptr | Stampa come stringa C |
(gdb) print x + y * 2 # espressioni aritmetiche (gdb) print (float)intvar # cast esplicito (gdb) print sizeof(struct node) # sizeof (gdb) print strlen(str) # chiama funzioni del programma! (gdb) print malloc(100) # alloca memoria (chiamata reale) # Variabili convenience (persistono nella sessione) (gdb) set $i = 0 (gdb) print arr[$i++] # usa e incrementa # Valore di ritorno dell'ultima print (gdb) print $ # ultimo valore stampato (gdb) print $$ # penultimo valore stampato (gdb) print $3 # valore della print #3
(gdb) set variable x = 42 (gdb) set variable *ptr = 99 (gdb) set variable str[0] = 'X' (gdb) set {int}0x601040 = 123 # scrivi direttamente in memoria
(gdb) info locals # tutte le variabili locali (gdb) info args # argomenti della funzione corrente (gdb) info variables # tutte le variabili globali/statiche (gdb) info variables ^my_ # variabili globali che matchano regex (gdb) info scope func # variabili visibili nel scope di func
(gdb) print arr # stampa intero array (se statico) (gdb) print arr[3] # singolo elemento (gdb) print *arr@10 # primi 10 elementi (artificial array) (gdb) print *(arr+5)@3 # 3 elementi a partire da arr[5] (gdb) print (int[10])*arr # cast a array di 10 int # Array 2D (matrice) (gdb) print matrix[2][3] # singolo elemento (gdb) print *matrix@rows # tutte le righe # Array di stringhe (char **) (gdb) print argv[0] (gdb) print *argv@argc # tutti gli argomenti
(gdb) print ptr # stampa l'indirizzo (gdb) print *ptr # dereferenzia: stampa il valore puntato (gdb) print **ptr # doppia dereferenziazione (gdb) print ptr->name # campo di struct via puntatore (gdb) print *node # stampa intera struct (gdb) print node->next->data # navigazione linked list # Percorri linked list manualmente (gdb) set $n = head (gdb) while $n != 0 > print *$n > set $n = $n->next > end
# Controllo della visualizzazione struct (gdb) set print pretty on # formattazione indentata per struct (gdb) set print pretty off (gdb) set print array on # un elemento per riga negli array (gdb) set print elements 0 # nessun limite (default: 200) (gdb) set print elements 50 # stampa max 50 elementi (gdb) set print null-stop on # ferma stampa array al primo 0 (gdb) set print union on # mostra contenuto union nelle struct (gdb) set print repeats 5 # comprimi sequenze ripetute (≥5 uguali)
I display stampano automaticamente un'espressione ad ogni stop (breakpoint, step, ecc.).
| Comando | Descrizione |
|---|---|
display x | Mostra x ad ogni stop |
display/x ptr | Mostra ptr in hex ad ogni stop |
display/i $pc | Mostra prossima istruzione assembly ad ogni stop |
display *arr@5 | Mostra primi 5 elementi ad ogni stop |
info display | Lista tutti i display attivi |
undisplay 2 | Rimuovi display #2 |
undisplay | Rimuovi tutti i display |
disable display 2 | Disabilita temporaneamente display #2 |
enable display 2 | Riabilita display #2 |
Il comando x (examine) ispeziona direttamente la memoria. Sintassi: x/NFS addr dove N=count, F=format, S=size.
| Lettera | Formato | Lettera | Formato |
|---|---|---|---|
x | Esadecimale | d | Decimale con segno |
u | Decimale senza segno | o | Ottale |
t | Binario | a | Indirizzo |
c | Carattere | f | Float |
s | Stringa C | i | Istruzione assembly |
| Lettera | Dimensione |
|---|---|
b | Byte (1 byte) |
h | Halfword (2 byte) |
w | Word (4 byte) — default |
g | Giant (8 byte) |
(gdb) x/10xw &arr # 10 word in hex dall'indirizzo di arr (gdb) x/20xb buf # 20 byte in hex (gdb) x/s str # stringa C (gdb) x/5s argv # 5 stringhe consecutive (gdb) x/10i $pc # 10 istruzioni dal program counter (gdb) x/10i main # 10 istruzioni dall'inizio di main (gdb) x/4gx $rsp # 4 quadword dallo stack pointer (gdb) x/16xb $rsp # 16 byte dallo stack in hex (gdb) x/xw 0x601040 # esame di indirizzo assoluto
(gdb) info proc mappings # mappa memoria del processo (gdb) info files # sezioni dell'eseguibile (gdb) info sharedlibrary # librerie condivise caricate (gdb) info address symbol # indirizzo di un simbolo (gdb) info symbol 0x4005a0 # simbolo all'indirizzo dato
(gdb) ptype x # tipo di una variabile (gdb) ptype struct node # definizione completa della struct (gdb) ptype enum color # valori di un enum (gdb) whatis x # tipo senza espandere (typedef preservato) (gdb) info types # tutti i tipi definiti (gdb) info types ^node # tipi che matchano regex
(gdb) info functions # tutte le funzioni (gdb) info functions ^parse # funzioni che matchano regex
| Comando | Abbr. | Descrizione |
|---|---|---|
backtrace | bt | Mostra lo stack trace completo |
backtrace full | bt full | Stack trace con variabili locali di ogni frame |
backtrace 5 | bt 5 | Solo i primi 5 frame |
backtrace -5 | bt -5 | Solo gli ultimi 5 frame |
frame N | f N | Seleziona il frame #N |
up | Vai al frame chiamante (su nello stack) | |
up N | Sali di N frame | |
down | Vai al frame chiamato (giù nello stack) | |
down N | Scendi di N frame | |
info frame | Informazioni dettagliate sul frame corrente | |
info registers | i r | Valori di tutti i registri |
info registers rax rbx | Valori di registri specifici | |
info all-registers | Tutti i registri (inclusi SSE, FPU, ecc.) |
(gdb) bt #0 segfault_func (ptr=0x0) at main.c:12 #1 0x00005555555551a0 in process (data=0x7fffffffde20) at main.c:25 #2 0x0000555555555210 in main (argc=2, argv=0x7fffffffdf48) at main.c:40 (gdb) frame 2 # vai al frame di main (gdb) info locals # variabili locali di main (gdb) info args # argc e argv di main
| Comando | Abbr. | Descrizione |
|---|---|---|
list | l | Mostra 10 righe intorno alla posizione corrente |
list 30 | l 30 | Mostra intorno alla riga 30 |
list 10,30 | Mostra dalla riga 10 alla 30 | |
list func | l func | Mostra il sorgente della funzione |
list file.c:42 | Mostra intorno alla riga 42 di file.c | |
list - | Mostra le 10 righe precedenti | |
set listsize 20 | Cambia il numero di righe mostrate |
(gdb) directory /path/to/src # aggiungi directory di sorgenti (gdb) show directories # mostra percorsi di ricerca sorgenti
| Comando | Descrizione |
|---|---|
disassemble | Disassembla la funzione corrente |
disassemble main | Disassembla main |
disassemble /m main | Disassembla con sorgente C interleaved |
disassemble /s main | Disassembla con sorgente (migliore di /m) |
disassemble /r main | Disassembla con raw bytes |
disassemble 0x4005a0,0x4005f0 | Disassembla range di indirizzi |
disassemble $pc,+50 | 50 byte dal program counter |
# Scegliere tra sintassi AT&T e Intel (gdb) set disassembly-flavor att # default su Linux (gdb) set disassembly-flavor intel # più leggibile per molti (gdb) show disassembly-flavor
(gdb) info registers # registri general-purpose (gdb) print/x $rip # program counter (gdb) print/x $rsp # stack pointer (gdb) print/x $rbp # base pointer (gdb) print/x $eflags # flags register (gdb) display/i $pc # mostra istruzione corrente ad ogni stop (gdb) x/10i $pc # prossime 10 istruzioni
GDB può seguire il processo padre o figlio dopo una fork(), o gestire entrambi contemporaneamente.
| Comando | Descrizione |
|---|---|
set follow-fork-mode parent | Segui il padre dopo fork (default) |
set follow-fork-mode child | Segui il figlio dopo fork |
show follow-fork-mode | Mostra la modalità corrente |
| Comando | Descrizione |
|---|---|
set detach-on-fork on | Il processo non seguito viene rilasciato (default) |
set detach-on-fork off | Entrambi i processi restano sotto GDB |
# Ogni processo è un "inferior" in GDB (gdb) info inferiors # lista tutti i processi (gdb) inferior 2 # passa al processo #2 (gdb) detach inferior 2 # rilascia il processo #2 (gdb) kill inferiors 2 # uccidi il processo #2 # Scheduling dei processi (gdb) set schedule-multiple on # tutti i processi eseguono quando fai continue (gdb) set schedule-multiple off # solo il processo corrente esegue (default)
(gdb) set detach-on-fork off # tieni entrambi (gdb) set follow-fork-mode child (gdb) break child_work # bp nella funzione del figlio (gdb) run ...fork() chiamata... [New inferior 2 (process 12346)] [Switching to inferior 2] (gdb) info inferiors Num Description Executable * 2 process 12346 /path/prog 1 process 12345 /path/prog (gdb) inferior 1 # torna al padre
GDB gestisce nativamente i programmi multi-thread. Compilare con -pthread e -g.
gcc -g -O0 -pthread main.c -o prog
| Comando | Descrizione |
|---|---|
info threads | Lista tutti i thread (il corrente ha *) |
thread N | Passa al thread #N |
thread apply all bt | Backtrace di tutti i thread |
thread apply all info locals | Variabili locali di tutti i thread |
thread apply 1 3 bt | Backtrace dei thread 1 e 3 |
thread name worker-1 | Assegna un nome al thread corrente |
# Breakpoint che si attiva solo per un thread specifico (gdb) break worker_func thread 3 (gdb) break 42 thread 2 if count > 10
# Controlla se gli altri thread eseguono durante lo stepping (gdb) set scheduler-locking off # tutti i thread eseguono (default) (gdb) set scheduler-locking on # solo il thread corrente esegue (gdb) set scheduler-locking step # lock durante step, free durante continue (gdb) show scheduler-locking
# In non-stop mode, solo il thread che hita il bp si ferma # Gli altri thread continuano a eseguire (gdb) set non-stop on # abilitare PRIMA di run (gdb) set target-async on # richiesto per non-stop # In non-stop mode: (gdb) interrupt # ferma il thread corrente (gdb) interrupt -a # ferma tutti i thread (gdb) continue -a # riprendi tutti i thread
thread apply all bt per vedere dove ogni thread è bloccato (tipicamente in pthread_mutex_lock).GDB intercetta i segnali e permette di controllare come vengono gestiti.
| Comando | Descrizione |
|---|---|
info signals | Lista segnali e come GDB li gestisce |
info signals SIGSEGV | Info su un segnale specifico |
handle SIGPIPE nostop noprint pass | Non fermare, non stampare, passa al programma |
handle SIGSEGV stop print nopass | Fermati, stampa, non passare al programma |
handle SIGUSR1 stop | Fermati su SIGUSR1 |
signal SIGCONT | Invia segnale al programma e riprendi |
signal 0 | Riprendi senza inviare il segnale pendente |
| Opzione | Descrizione |
|---|---|
stop / nostop | Fermati / non fermarti quando il segnale arriva |
print / noprint | Stampa / non stampare un messaggio |
pass / nopass | Passa / non passare il segnale al programma |
I catchpoints intercettano eventi specifici del sistema (syscall, eccezioni, ecc.).
| Comando | Descrizione |
|---|---|
catch syscall | Ferma ad ogni syscall |
catch syscall write | Ferma solo alla syscall write |
catch syscall open close | Ferma a open o close |
catch fork | Ferma quando il programma chiama fork() |
catch vfork | Ferma su vfork() |
catch exec | Ferma su exec() |
catch throw | Ferma quando viene lanciata un'eccezione C++ |
catch catch | Ferma quando un'eccezione C++ viene catturata |
catch load libname | Ferma al caricamento di una libreria condivisa |
catch signal SIGSEGV | Ferma quando il programma riceve un segnale |
tcatch throw | Catchpoint temporaneo (una sola volta) |
GDB supporta il debug "all'indietro": registra l'esecuzione e poi naviga avanti e indietro nel tempo.
(gdb) target record-full # inizia a registrare (dopo start/run) (gdb) record # alias di target record-full (gdb) record stop # ferma la registrazione (gdb) info record # stato della registrazione
| Comando | Abbr. | Descrizione |
|---|---|---|
reverse-continue | rc | Esegui all'indietro fino al breakpoint precedente |
reverse-step | rs | Step into al contrario |
reverse-next | rn | Step over al contrario |
reverse-finish | Torna all'inizio della funzione corrente | |
reverse-stepi | rsi | Step indietro di una istruzione macchina |
reverse-nexti | rni | Nexti al contrario |
set exec-direction reverse | Tutti i comandi di stepping vanno all'indietro | |
set exec-direction forward | Torna alla direzione normale |
record-full è molto lento. Per performance migliori, considera record btrace (richiede supporto hardware Intel PT) o strumenti come rr (rr record ./prog poi rr replay).GDB può eseguire il debug di programmi su macchine remote tramite gdbserver.
# Sul target remoto (la macchina dove gira il programma) gdbserver :1234 ./prog arg1 arg2 gdbserver --attach :1234 12345 # attach a PID esistente # Sul host (la macchina di sviluppo) (gdb) target remote 192.168.1.100:1234 (gdb) target remote :1234 # se locale (stessa macchina) # Extended remote (permette di riavviare il programma) gdbserver --multi :1234 (gdb) target extended-remote :1234 (gdb) set remote exec-file /path/to/prog (gdb) run
(gdb) monitor help # comandi del server remoto (gdb) disconnect # disconnetti dal target (gdb) set sysroot /path/to/libs # librerie del target
Si possono associare comandi ad un breakpoint: vengono eseguiti automaticamente ogni volta che il bp scatta.
# Esegui comandi quando bp #1 scatta (gdb) commands 1 > silent # non stampare il messaggio di stop > printf "i=%d, x=%f\n", i, x > continue # riprendi automaticamente > end # Logging personalizzato (printf-style debugging senza modificare il codice) (gdb) break process_data (gdb) commands > silent > printf "[LOG] process_data called: n=%d, ptr=%p\n", n, ptr > backtrace 3 > continue > end # Dprintf: breakpoint con printf integrato (non si ferma) (gdb) dprintf main.c:42, "x=%d y=%d\n", x, y
(gdb) set logging file gdb.log (gdb) set logging on # inizia a registrare l'output ... esegui comandi ... (gdb) set logging off # ferma la registrazione # Redirect output solo al file (non al terminale) (gdb) set logging redirect on
| File | Descrizione |
|---|---|
~/.gdbinit | Eseguito all'avvio di ogni sessione GDB |
./.gdbinit | Eseguito se presente nella directory corrente |
gdb -x file.gdb | Esegui comandi dal file specificato |
# ~/.gdbinit set disassembly-flavor intel set print pretty on set print array on set pagination off set confirm off set history save on set history size 10000 set history filename ~/.gdb_history # Abilita .gdbinit locali (necessario dalla versione 8+) set auto-load safe-path / # Alias personalizzati alias -a bta = thread apply all backtrace
# Definisci un comando personalizzato (gdb) define print_list > set $node = $arg0 > set $i = 0 > while $node != 0 > printf "[%d] data=%d addr=%p\n", $i, $node->data, $node > set $node = $node->next > set $i = $i + 1 > end > printf "Total: %d nodes\n", $i > end (gdb) print_list head # usa il comando personalizzato
# GDB ha un interprete Python integrato (gdb) python print(gdb.breakpoints()) (gdb) python print(gdb.parse_and_eval("x")) # Script Python più complesso (gdb) python > import gdb > for t in gdb.selected_inferior().threads(): > print(f"Thread {t.num}: {t.name or 'unnamed'}") > end # Pretty printer personalizzato (in .gdbinit o file Python) python class VectorPrinter: def __init__(self, val): self.val = val def to_string(self): x = self.val['x'] y = self.val['y'] return f'Vec2({x}, {y})' def vec_lookup(val): if str(val.type) == 'struct vec2': return VectorPrinter(val) return None gdb.pretty_printers.append(vec_lookup) end
La TUI mostra il sorgente, l'assembly, i registri e il comando in pannelli separati all'interno del terminale.
| Comando / Tasto | Descrizione |
|---|---|
gdb -tui prog | Avvia GDB direttamente in TUI |
tui enable | Attiva TUI in una sessione già avviata |
tui disable | Disattiva TUI |
Ctrl+X, A | Toggle TUI on/off |
Ctrl+X, 1 | Layout a singolo pannello |
Ctrl+X, 2 | Layout a doppio pannello |
Ctrl+X, O | Cambia pannello attivo |
Ctrl+L | Ridisegna lo schermo |
| Comando | Descrizione |
|---|---|
layout src | Solo sorgente + comandi |
layout asm | Solo assembly + comandi |
layout split | Sorgente + assembly + comandi |
layout regs | Aggiunge il pannello registri |
layout next | Passa al prossimo layout |
layout prev | Torna al layout precedente |
focus src | Focus sul pannello sorgente |
focus asm | Focus sul pannello assembly |
focus cmd | Focus sul pannello comandi |
focus regs | Focus sul pannello registri |
winheight src +5 | Aumenta altezza del pannello sorgente |
winheight src -5 | Riduci altezza |
(gdb) tui reg general # mostra registri general-purpose (gdb) tui reg float # mostra registri floating-point (gdb) tui reg sse # mostra registri SSE (gdb) tui reg all # mostra tutti i registri
tui disable e poi tui enable.Analizzare core dump per capire crash post-mortem.
# Abilita core dump nel sistema ulimit -c unlimited # Verifica dove vengono salvati cat /proc/sys/kernel/core_pattern # Genera un core dump da GDB (gdb) generate-core-file # salva core.PID (gdb) generate-core-file my.core
# Apri il core dump gdb ./prog core # Comandi utili per l'analisi (gdb) bt # dove è crashato? (gdb) bt full # con variabili locali (gdb) info registers # stato registri al crash (gdb) info locals # variabili locali (gdb) frame 0 # vai al frame del crash (gdb) list # sorgente del punto di crash (gdb) print *ptr # ispeziona il puntatore che ha causato SIGSEGV
(gdb) print $_ # ultimo indirizzo esaminato con x (gdb) print $__ # ultimo valore esaminato con x (gdb) print $_exitcode # exit code dell'ultimo run (gdb) print $_siginfo # info sull'ultimo segnale ricevuto (gdb) print $_thread # numero del thread corrente
# Chiama funzioni del programma o della libc (gdb) call printf("debug: x=%d\n", x) (gdb) call free(ptr) (gdb) call (void)close(fd) # cast per ignorare il return value
# Salva lo stato del processo (come una snapshot) (gdb) checkpoint # crea un checkpoint (fork del processo) (gdb) info checkpoints (gdb) restart 1 # torna al checkpoint #1 (gdb) delete checkpoint 1
# Cerca un pattern in memoria (gdb) find /b 0x601000, 0x602000, 0x41, 0x42, 0x43 # cerca "ABC" (gdb) find &buf, +sizeof(buf), "ERROR" # cerca stringa (gdb) find /w 0x601000, +0x1000, 0xDEADBEEF # cerca word
# Avvia Valgrind con GDB server integrato valgrind --vgdb=yes --vgdb-error=0 ./prog # In un altro terminale gdb ./prog (gdb) target remote | vgdb
# Per debuggare macro, compilare con: gcc -g3 -gdwarf-4 -O0 main.c -o prog (gdb) info macro MAX_SIZE # definizione di una macro (gdb) macro expand MAX(a,b) # espansione di una macro (gdb) info macros 42 # tutte le macro visibili alla riga 42
| Abbreviazione | Comando completo |
|---|---|
r | run |
c | continue |
s | step |
n | next |
fin | finish |
u | until |
b | break |
d | delete |
p | print |
bt | backtrace |
f | frame |
l | list |
q | quit |
i b | info breakpoints |
i r | info registers |
i lo | info locals |
i th | info threads |