2009-08-25 14 views
6

Ho un'applicazione. Ho il codice sorgente (in C). Posso compilarlo comunque, voglio. Aggiungi qualsiasi strumento lo voglio. Tuttavia, non voglio addolcire il codice sorgente con un gruppo di printf. Voglio essere in grado di produrre un log di qualche tipo che mostri quando un valore particolare (ad esempio un membro di una struttura globale) viene scritto (il suo valore cambia). Mi piacerebbe essere in grado di mostrare il file sorgente e il numero di riga e il vecchio e il nuovo valore.aiuto con tracce gdb (o simili)

Vorrei anche essere in grado di specificare il valore per nome, non indirizzo. Ma l'indirizzo è OK. Punti bonus se posso specificare un valore che è locale per una funzione.

Mi sto ancora grattando la testa cercando di capire i comandi di traccia di gdb. Qualsiasi aiuto è molto apprezzato. Grazie.

risposta

1

Grazie a entrambi @derobert e @peter! Sono finalmente tornato a questo, e questo:

break main 
commands 
     watch somevar 
     commands 
       cont 
     end 
     cont 
end 
run 

fa il trucco. Funziona quando "somevar" è globale o locale a "main". Se "somevar" è locale alla funzione anther, basta sostituire "main" con il nome di quella funzione sopra.

mettere questi comandi in un file (ad esempio "gdbscript") e gdb Run Like:

gdb -x gdbscript a.out 
6

Innanzitutto, è necessario assicurarsi di compilare il programma con i simboli di debug e probabilmente senza l'ottimizzazione per rendere più utile gdb. Per gcc, sarebbe -g -O0.

In secondo luogo, la funzione che stai cercando non è la traccia, i suoi punti di controllo.

(gdb) help watch 
Set a watchpoint for an expression. 
A watchpoint stops execution of your program whenever the value of 
an expression changes. 

Quindi, dato un po 'di codice di esempio:

int main() { 
    int a; 
    a = 1; 
    a = 2; 
    return 0; 
} 

è quindi possibile eseguire gdb su di esso, e:

(gdb) b main 
Breakpoint 1 at 0x80483a5: file test.c, line 4. 
(gdb) run 
Starting program: /tmp/test 

Breakpoint 1, main() at test.c:4 
4    a = 1; 
(gdb) watch a 
Hardware watchpoint 2: a 
(gdb) c 
Continuing. 
Hardware watchpoint 2: a 

Old value = -1207552288 
New value = 2 
main() at test.c:8 
8    return 0; 

sta funzionando un po' divertente a causa di un essere in pila, non memoria E se l'ottimizzazione fosse attiva, funzionerebbe ancora meno: a sarebbe stata ottimizzata.

+1

Prova dichiarando 'a' come' int' volatile, che può rendere l'esempio funzionare meglio. – caf

+0

Grazie derobert. Da quello che ho capito sugli orologi è che fanno cessare l'esecuzione del programma fino a quando l'utente "continua". Sono sicuro di poter scrivere uno script previsto per fare ciò, ma è in qualche modo possibile farlo automaticamente da gdb? – tvaughan

+0

@tvaughan: Non conosco un modo automatico per farlo in gdb. – derobert

3

Come già detto, è necessario impostare un punto di controllo sulla variabile.

La si utilizza il comando "comandi"

(gdb) help commands 
Set commands to be executed when a breakpoint is hit. 
Give breakpoint number as argument after "commands". 
With no argument, the targeted breakpoint is the last one set. 
The commands themselves follow starting on the next line. 
Type a line containing "end" to indicate the end of them. 
Give "silent" as the first line to make the breakpoint silent; 
then no output is printed when it is hit, except what the commands print. 

Quindi, trovare il numero watchpoint dal comando watch, e fare questo (supponendo che l'orologio è la seconda pausa)

(gdp) commands 2 
> print a 
> cont 
> end 

Assumendo a è la variabile che vuoi. Puoi lasciare la linea di stampa se sei soddisfatto dell'output di gdb.

È inoltre possibile utilizzare i comandi nel punto di interruzione originale per impostare il punto di controllo e continuare.