GDB
Da Wikipedia, l'enciclopedia libera.
Introduzione: Cos'è un debugger?
Dopo aver creato un qualsiasi programma, è buona norma controllare che faccia esattamente ciò per cui è stato progettato. Tipicamente basta guardare il codice attentamente per capire se il programma commette degli errori oppure no, ma spesso può succedere che
- sappiamo che c'è un errore ma comunque non riusciamo a trovarlo
- non ci siamo accorti di alcun errore nel codice ma il programma ha comunque un errore nascosto che non salta subito all'occhio e che in certi casi rari potrebbe causare qualche problema
Nel primo caso sappiamo che l'errore esiste ma non riusciamo a trovarlo neanche rileggendo il codice più volte. Il secondo caso è più insidioso, perché all'inizio tutto sembra funzionare bene, ma poi si verifica inaspettatamente qualcosa che non avevamo previsto. In ambedue i casi, un buon modo per risolvere il problema sarebbe eseguire il programma riga per riga, controllando passo passo e in tempo reale quali operazioni esegue e qual è il valore che assumono le variabili in ogni istante. Soltanto un'analisi accurata del programma durante la sua esecuzione può permetterci di scovare gli errori visibili e invisibili. Ma come si può eseguire un programma una riga alla volta? Fortunatamente esistono programmi appositi che svolgono proprio questo compito. Questi programmi sono detti debugger (in gergo informatico, il bug è un errore nel programma; l'operazione di rimozione dell'errore è detta debugging).
Il debugger GNU
In questo articolo ci occuperemo del debugger GNU sotto un sistema operativo GNU/Linux. Questo debugger riesce ad analizzare programmi scritti in vari linguaggi (C, C++ etc.). Affinché il debugger GNU funzioni correttamente sul nostro programma, è necessario compilare il codice con l'opzione '-g'. Ad esempio, se il codice di un programma in linguaggio C è contenuto nel file 'programma.c', il modo corretto di compilare sarà
gcc -g -o prog programma.c
In questo modo, abbiamo creato il file autoeseguibile 'prog'. Per eseguire il debugger e farlo lavorare su di esso, basta digitare
gdb prog
Dovrebbe apparire una schermata di questo tipo
GNU gdb 6.4.90-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu". (gdb)
Adesso dobbiamo comunicare al debugger almeno un breakpoint, ovvero una riga di codice o una funzione alla quale interrompere l'esecuzione del programma. Una volta interrotto il programma, sarà possibile eseguirlo riga per riga in una maniera che mostreremo tra un attimo. Per mettere un breakpoint in corrispondenza, per esempio, della funzione 'main', basta digitare
(gdb) break main
Se invece si vuole mettere il breakpoint in una riga ben precisa, per esempio la riga 71, la sintassi è la seguente
(gdb) break 71
Se il programma è composto da vari file compilati assieme, è possibile specificare anche il nome del file a cui appartiene la riga in cui vogliamo mettere il breakpoint. Basta separare il nome del file dal numero di riga con un carattere di due punti ':'.
(gdb) break programma.c:71
Possiamo specificare quanti breakpoint desideriamo. Dopo ogni breakpoint, dovrebbe comparire un messaggio del tipo
Breakpoint 1 at 0x8048365: file programma.c, line 5.
Il numero che segue la parola 'breakpoint' (in questo caso, 1), identifica univocamente il breakpoint nel programma. Se, per esempio, vogliamo rimuovere un breakpoint, basta digitare
(gdb) delete break 1
A questo punto, bisogna eseguire il programma. Per farlo, basta usare il comando 'run'
(gdb) run
In questo modo, il debugger esegue il programma dalla prima riga in poi, fermandosi al primo breakpoint incontrato durante l'esecuzione. Se il nostro programma riceve argomenti dalla riga di comando, basta specificarli dopo 'run'
(gdb) run argomento1 argomento2 argomento3
Adesso siamo fermi a un breakpoint. Il debugger ci mostra una riga di codice. Questa riga non è stata ancora eseguita. In questo momento possiamo fare molte cose. Per esempio, possiamo stampare sullo schermo il valore di una variabile (i comandi di gdb possono essere anche abbreviati; negli esempi successivi mostreremo sia la dicitura per intero che una abbreviazione. L'effetto è assolutamente equivalente)
(gdb) print nomevariabile (gdb) p nomevariabile
Oppure possiamo vedere una porzione di codice prima e dopo la riga attuale
(gdb) list (gdb) l
In alternativa, possiamo impostare a mano il valore di una variabile
(gdb) set var variabile=valore
Una volta fatto tutto questo, possiamo muoverci alla riga successiva. Per farlo si può usare il comando 'next'
(gdb) next (gdb) n
Questo comando salta alla riga successiva della porzione di codice attuale. Se la riga attuale è la chiamata a una funzione, con 'next' non entriamo dentro la funzione, ma passiamo alla riga elaborata dopo la sua esecuzione. Se invece volessimo entrare nella funzione, si usa il comando 'step'
(gdb) step (gdb) s
Se desideriamo mostrare costantemente sullo schermo il valore di alcune variabili, basta usare 'display'
(gdb) display variabile
Il risultato sarà una riga del tipo:
1: variabile = -1208249712
Il numero precedente il simbolo ':' è l'identificativo del 'display'. Per rimuovere questa variabile dalla visualizzazione costante, basta usare il solito 'delete'
(gdb) delete disp 1
Se invece vogliamo che il programma continui a lavorare fino al breakpoint successivo si usa 'continue'
(gdb) continue (gdb) c
Infine, per uscire dal debugger, basta usare 'quit'
(gdb) quit (gdb) q
Se invece desideriamo avere più informazioni su un determinato comando, possiamo usare 'help'
(gdb) help nomecomando
Questi sono i comandi più importanti. Questa guida non ha la pretesa di essere esaustiva, tuttavia dovrebbe darvi un'idea abbastanza chiara di come utilizzare in pratica uno strumento potente come il debugger GNU.
Fonti / Citazioni
- Articolo Tratto da www.tuxino.com
- Autore Gianluca Malato, 17 Novembre 2007 (created 16 Novembre 2007)
