OldWildWeb Logo

Debug errore segmentation fault con GDB

Risolvere un errore di segmentazione nei programmi in C con GDB

debug programmi in c gdb
GDB il potente debugger per C, impariamo ad utilizzarlo con dei comandi base

Debug dei programmi in C con DDB, risolvere l'errore di segmentazione

I programmi scritti in C, potrebbero facilmente crashare a causa di un classico buffer overflow, le caratteristiche del C a basso livello lo rendono un linguaggio un pò più difficile rispetto altri basta una piccola distrazione e l'errore di segmentation fault può verificarsi in maniera inaspettata!

Quando ci si trova di fronte ad un buffer overflow all'interno di programmi complessi, individuare il punto esatto dove si trova l'errore potrebbe risultare molto difficile, la ricerca di un bug in un codice grande potrebbe essere paragonata a cercare l'ago nel pagliaio, fortunatamente esiste il debugger GDB che consente di individuare in maniera rapida e veloce l'errore anche nei codici più complicati.

Esaminiamo qui sotto un semplicissimo programma con un errore:
1] 
2]
3]
4] void main()
5] {
6]
7] char *s;
8] s = NULL;
9]
10] sprintf(s, "12345678");
11] printf("%s", s);
12]
13] return;
14]
15] }

Proviamo a compilare ed eseguire il programma qui sopra:
$gcc  test.c -o test
$ ./test
Errore di segmentazione

Nel codice qui sopra si può intuire facilmente l'errore presente nella riga 10, si cerca di scrivere una stringa in un puntatore non inizializzato NULL.
Supponendo di non sapere dove si trova l'errore proviamo ad utilizzare GDB per individuarlo.

Ricompiliamo il programma con i flag di debug -g e utilizziamo gdb per effettuare il debug :
$gcc -g  test.c -o test
$ gdb ./test
(gdb) run

Starting program: /gdb/test

Program received signal SIGSEGV, Segmentation fault.
0x000000000040054f in main () at test.c:10
10 sprintf(s,"12345678");

Con il comando "gcc -g test.c -o test" il programma è stato ricompilato con il flag di debug -g necessario a GDB per effettuare correttamente il debug, con il comando "gdb ./test" abbiamo caricato il programma test nel debugger gdb, infine con il comando "run" gdb ha avviato l'applicazione restituendo come output la riga del codice dove si trova il bug, linea 10.

Per entrare più in dettaglio negli errori riscontrati possiamo utilizzare il comando gdb backtrace:
(gdb) backtrace
#0 0x000000000040054f in main () at test.c:10

Per entrare nei dettagli dei singoli errori utilizziamo invece il comando frame, specificando l'id dell'errore nel nostro caso:
(gdb) frame 0
#0 0x000000000040054f in main () at test.c:10
10 sprintf(s,"12345678");

Possiamo visualizzare il contenuto delle variabili con il comando print al momento del crash:
(gdb) print s
$1 = 0x0

La variabile s come si può notare conteneva un valore NULL 0x0
Chiudiamo il programma e piazziamo un breakpoint prima della riga 10 per debuggare meglio il codice
(gdb) kill
Kill the program being debugged? (y or n) y
(gdb) break test.c:8
Breakpoint 1 at 0x400535: file test.c, line 8.

(gdb) run
Starting program: /gdb/test

Breakpoint 1, main () at test.c:8
8 s = NULL;

Dopo aver piazzato un breakpoint è possibile scorrere le linee tramite il comando next e vedere cosa si verifica stampando quando si ritriene opportuno i valori delle variabili con il comando print



debug programmi in c gdb



Articoli correlati