GDB - Esempio di debug 2
Scriviamo un altro programma che provocherà un core dump a causa della memoria non inizializzata.
#include <iostream>
using namespace std;
void setint(int*, int);
int main()
{
int a;
setint(&a, 10);
cout << a << endl;
int* b;
setint(b, 10);
cout << *b << endl;
return 0;
}
void setint(int* ip, int i)
{
*ip = i;
}
Per abilitare il debug, il programma deve essere compilato con l'opzione -g.
$g++ -g crash.cc -o crash
NOTE: Stiamo usando il compilatore g ++ perché abbiamo usato il codice sorgente C ++.
Quando esegui questo programma sulla tua macchina Linux, produrrà il seguente risultato:
segmentation fault (core dumped)
Ora eseguiamo il debug utilizzando gdb:
$ gdb crash
(gdb) r
Starting program: /home/tmp/crash
10
10
Program received signal SIGSEGV, Segmentation fault.
0x4000b4d9 in _dl_fini () from /lib/ld-linux.so.2
(gdb) where
#0 0x4000b4d9 in _dl_fini () from /lib/ld-linux.so.2
#1 0x40132a12 in exit () from /lib/libc.so.6
#2 0x4011cdc6 in __libc_start_main () from /lib/libc.so.6
#3 0x080485f1 in _start ()
(gdb)
Sfortunatamente, il programma non andrà in crash in nessuna delle funzioni definite dall'utente, main o setint,quindi non ci sono tracce utili o informazioni sulle variabili locali. In questo caso, può essere più utile eseguire un singolo passaggio nel programma.
(gdb) b main
# Set a breakpoint at the beginning of the function main
(gdb) r
# Run the program, but break immediately due to the breakpoint.
(gdb) n
# n = next, runs one line of the program
(gdb) n
(gdb) s
setint(int*, int) (ip=0x400143e0, i=10) at crash2.C:20
# s = step, is like next, but it will step into functions.
# In this case the function stepped into is setint.
(gdb) p ip
$3 = (int *) 0x400143e0
(gdb) p *ip
1073827128
Il valore di * ip è il valore dell'intero puntato da ip. In questo caso, è un valore insolito ed è una forte prova che c'è un problema. Il problema in questo caso è che il puntatore non è mai stato inizializzato correttamente, quindi punta a un'area casuale in memoria (l'indirizzo 0x40014e0). Per pura fortuna, il processo di assegnazione di un valore a * ip non blocca il programma, ma crea qualche problema che blocca il programma quando finisce.