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.