2008-09-26 9 views
12

Come sviluppatore, come usi gdb per rintracciare i bug all'interno del tuo codice? Quali trucchi di tecnica usi per semplificarti la vita?Come usi gdb per eseguire il debug del tuo codice?

+0

Mi facilito la vita utilizzando un IDE che integra GDB!;) – Dan

+0

Che è bello quando è un'opzione. Mi è stato detto che il mio lavoro si unirà al 21 ° secolo in un anno o due. Tuttavia, è sempre utile sapere come fare qualcosa manualmente per beneficiare di tutte le funzionalità, come l'esecuzione delle proprie funzioni con variabili dal punto corrente nel codice. –

risposta

2

In generale si trova qualcosa che non è come dovrebbe essere, e si lavora all'indietro finché non si capisce il perché.

Il più ovvio è il più utile: impostare un punto di interruzione su una funzione o un numero di linea e camminare lungo il codice riga per riga.

Un altro suggerimento utile è quello di avere Mostra funzioni per tutte le strutture/oggetti anche se non vengono mai utilizzate nel programma, perché è possibile eseguire queste funzioni all'interno di gdb:

gdb> p show_my_struct(struct) 

My custom display of Foo: 
    ... 

watchpoints può essere davvero a portata di mano troppo, ma potrebbe rallentare molto il tuo programma. Questi rompere il flusso quando il valore di una variabile o indirizzo modifiche .:

gdb> watch foo 
Watchpoint4: foo 
gdb> 
+0

Perché non semplicemente "p my_struct", invece di "p show_my_struct (my_struct)"? – sigjuice

+0

Poiché è possibile decodificare il campo flags, eseguire il codice di convalida, ecc. Non è semplicemente un dump dei valori della struttura, è possibile invece dump il significato, inclusi gli oggetti rilevanti a cui è rivolto. Ad esempio, se obj1 ha una lista di obj2s, allora puoi annidare uno show di tutti gli oggetti in là. –

3

alcuni suggerimenti:

  • utilizzare un'interfaccia grafica (KDbg è abbastanza buona, ddd è almeno meglio di riga di comando gdb, kdevelop ha un bel frontend gdb ma ha qualche bgs, anche il nemiver sembra piuttosto carino ma è ancora in lavorazione)
  • assicurati di avere i simboli di debug e il codice sorgente per tutte le parti importanti (il tuo codice e anche qualche sistema libs)
    • su RedHat, è possibile installare i pacchetti -debuginfo per far apparire magicamente sia i simboli che il codice sorgente nel debugger - veramente bello perché si possono esaminare le chiamate della funzione libc ecc.
    • su Debian/Ubuntu, è possibile installare il - pacchetti dbg per ottenere simboli; l'installazione di file sorgente appropriati per pacchetti di sistema sembra essere difficile, sebbene
  • tendo ad aggiungere chiamate assert() e abort() in luoghi che non devono essere raggiunti, o in luoghi che voglio studiare (qualche tipo di punto di rottura pesante)
  • idealmente le chiamate assert() o abort() devono essere racchiuse in qualche metodo o macro che le abiliti solo nelle versioni di Debug, o meglio che le abilitino solo se è impostata una certa env var
  • installa un gestore di segnale per SIGSEGV e SIGABRT; personalmente controllo se un certo env var è impostato prima di installare i gestori; e nel gestore eseguo un comando esterno hardcoded che di solito vive da qualche parte in ~/.local/bin /; quel comando potrebbe quindi avviare kdbg e collegarlo all'app che si blocca. Voila, il debugger si apre nel momento in cui la tua app fa qualcosa di male.
  • Se si utilizzano i test di unità, è possibile allegare un debugger in modo simile ogni volta che un test fallisce, per ispezionare l'app.
+0

In realtà le asserzioni vengono normalmente rimosse durante la creazione senza debug (-g). Da ASSERT (3): "Se la macro NDEBUG è stata definita al momento dell'ultimo , la macro assert() non genera alcun codice e quindi non fa nulla". –

+0

Non sono sicuro che lo chiamerei "normalmente". Di solito mantengo le mie affermazioni, e penso anche che il fatto di dover usare la macro NDEBUG (al contrario, per esempio, di non definire una macro "DEBUG") suggerisce che i progettisti di assert concordano sul fatto che gli asserti dovrebbero di solito rimanere. –

0

Utilizzare ddd, un front-end visivo per gdb. Ti permette di fare le cose facilmente con pochi clic del mouse e visualizzare come funziona il codice, inoltre nella console del debugger hai un gdb intercalato.

2

Una caratteristica particolarmente utile di gdb è la sua capacità di ispezionare lo stato finale di un programma in crash.

di ispezionare un crash dump (o file core, come è più comunemente chiamato), avviare gdb come segue:

gdb < nome-programma > < core-file di >

Ad esempio:

gdb a.out nucleo

Upon runn ing questo comando su un file core, gdb vi dirà come il programma terminato e visualizzare le quali il programma si è verificato l'errore:

Program terminated with signal 11, Segmentation fault. 
#0 0x08048364 in foo() at foo.c:4 
4   *x = 100; 

Nell'esempio di cui sopra, si può vedere che il programma è terminato con un errore di segmentazione, mentre cercando di assegnare un valore a un puntatore. Digitando backtrace (o bt o dove) al prompt di gdb, è possibile visualizzare backtrace completo del programma:

(gdb) backtrace 
#0 0x08048364 in foo() at foo.c:4 
#1 0x0804837f in main() at foo.c:9 

A questo punto, si sa che main() chiamato foo() e foo() si è schiantato sulla linea 4 durante il tentativo di assegnare un valore a *x. Molte volte, questo fornisce informazioni sufficienti per consentire di correggere il bug.

1

Realizzo molti programmi paralleli, quindi ho scoperto che l'utilizzo di un semplice wrapper in python/ruby ​​che mi consente di avere gdb collegato a tutti i processi su tutti i nodi e di comunicare a me è straordinariamente utile (non ho trovato un modo migliore se qualcuno sa di uno, di non dirottare il filo, anche se ...)

io non sono sicuro di come sperimentato l'OP è, quindi:

la documentazione GDB sono molto carino e onnicomprensivo. Il primo capitolo è una buona introduzione a tutte le basi.

http://www.gnu.org/software/gdb/documentation/

Anche se non gdb, essi sono correlati: Ho personalmente trovato che rompere le linee complesse verso il basso per aiutare a determinare quali dichiarazioni si erroring aiuta.

Inoltre, Valgrind (http://valgrind.org/) è veramente bello/utile per affrontare buffer overflow e simili (non ho avuto fortuna con gdb per fare questo

1

di base ma molto utile -. Utilizzare la text gui con la opzione -tui.

+1

È possibile attivare la modalità gdb tui utilizzando CTRL-X CTRL-A – ciceron