go
In questo corso consigliamo di definire un comando custom chiamato go
in gdb
. Per definirlo occorre editare il file .gdbinit
all’interno della home dell’utente. Ad esempio sulla VM BIAR, possiamo editarlo con:
$ geany ~/.gdbinit
Dove ~/
denota la home directory dell’utente loggato nel sistema.
Inserire nel file il seguente contenuto:
define go
start
layout src
layout regs
focus cmd
end
Per facilitare la fase di debugging di un programma, dobbiamo compilare il binario utilizzando anche la flag -g
. Ad esempio:
gcc -m32 e_main.c e.s -o e -g
Dove e.s
contiene il nostro codice ASM e e
sarà l’eseguibile generato.
Per avviare la fase di debugging su un eseguibile e
:
$ gdb ./e
Avvio e terminazione:
(gdb) go // esegue uno script che lancia il debugging del programma e si ferma sulla prima istruzione del main
(gdb) run [<arg1> ...] // per (ri)lanciare l'esecuzione con eventuali argomenti
(gdb) quit // per uscire da gdb (o CTRL-d)
Controllo esecuzione:
(gdb) cont // per riprendere l'esecuzione normalmente dopo un breakpoint
(gdb) step // prosegue l'esecuzione di una singola istruzione
(gdb) next // esegue istruzione in modo atomico: se è una chiamata a funzione, viene eseguita fino al suo return
(gdb) finish // esegue fino al termine della funzione corrente
Gestione breakpoint:
(gdb) break e.c:20 // inserisco un breakpoint alla linea 20 di e.c
(gdb) break e.s:20 // inserisco un breakpoint alla linea 20 di e.s
(gdb) info break // per mostrare breakpoint attivi
(gdb) clear e.s:20 // per eliminare breakpoint su una locazione di riferimento
(gdb) delete 1 // per eliminare il breakpoint contrassegnato come 1 da 'info break'
Ispezione dello stato:
(gdb) print $eax // stampa il contenuto di un registro
(gdb) print x // stampa il contenuto della variabile x nello stack frame corrente
(gdb) x addr // stampa il contenuto della memoria all'indirizzo addr
(gdb) x $eax + 4 // stampa il contenuto della memoria all'indirizzo dat dall'espressione (eax + 4)
(gdb) x/nfu addr // stampa il contenuto della memoria all'indirizzo addr secondo un formato.
Formato nfu
(documentazione):
n
: quante volte si ripete un dato (repeat count), default=1, utile per stampare arrayf
: tipo del dato (‘x’, ‘d’, ‘u’, ‘o’, ‘t’, ‘a’, ‘c’, ‘f’, ‘s’)u
: dimensione del dato (‘b’: 1, ‘h’: 2, ‘w’: 4, ‘g’: 8)Abbreviazioni dei comandi:
print
=> p
next
=> n
cont
=> c
step
=> s
Altri comandi:
(gdb) start // si posiziona all'inizio del main; non necessario quando si usa go
(gdb) file <nome_eseguibile> // per caricare un eseguibile
(gdb) break e.c:20 if x == 0 // breakpoint condizionale: si ferma solo se quando la riga 20 è eseguita x è uguale a zero
(gdb) frame n // selezione frame (utile per ispezionare lo stato)
(gdb) where // mostra la posizione corrente nell'esecuzione
(gdb) list // mostra il contenuto del file sorgente che contiene la funzione corrente
(gdb) backtrace // elenco frame attivi