2010-03-15 5 views
12

Su un grande applicazione C, ho impostato un watchpoint hardware su un indirizzo di memoria come segue:Punto di controllo hardware GDB molto lento - perché?

(gdb) watch *0x12F5D58 
Hardware watchpoint 3: *0x12F5D58 

Come si può vedere, si tratta di un watchpoint hardware, non il software, il che spiegherebbe la lentezza.

Ora il tempo di esecuzione dell'applicazione in debugger è stato modificato da meno di dieci secondi a un'ora e il conteggio. Il watchpoint è stato attivato tre volte fino a quel momento, la prima volta dopo 15 minuti quando la pagina di memoria contenente l'indirizzo è stata resa leggibile da sbrk. Sicuramente durante quei 15 minuti il ​​watchpoint avrebbe dovuto essere efficiente dato che la pagina di memoria era inaccessibile? E questo ancora non spiega, perché è così lento in seguito.

La piattaforma è x86_64 e le versioni GDB sono Ubuntu 9.10 pacchetto:

$ gdb --version 
GNU gdb (GDB) 7.0-ubuntu 
[...] 

e magazzino GDB 7.1 costruita da fonti:

$ gdb-7.1 --version 
GNU gdb (GDB) 7.1 

Grazie in anticipo per eventuali idee come quello che potrebbe essere il causa o come risolvere/lavorare intorno ad esso.

EDIT: rimosso gettato

EDIT: gdb 7.1

+0

È sempre lento quando si esegue con il debugger o solo quando è impostato un watchpoint? – Gabe

+1

Solo con watchpoint. –

risposta

5

In realtà ho avuto problemi con i watchpoint hardware in GDB 7.x.x., il che non è accettabile poiché i watchpoint sono una necessità nel mio lavoro.

Su consiglio di un collega, ho scaricato il sorgente per 6.7.1 e lo ho creato localmente. I watchpoint funzionano molto meglio ora.

Potrebbe valere la pena provare.

+0

Interessante. Ci proverò. –

+1

GDB 6.7.1 manca una funzione in cui è possibile utilizzare i punti di controllo sull'indirizzo di memoria inaccessibile al momento della configurazione del punto di controllo. È possibile abilitarlo al momento giusto, ma questo sarà più coinvolto, proverò più tardi. Ho anche provato appena rilasciato GDB 7.1, lo stesso problema con 7.0. –

+0

con i breakpoint condizionali e i comandi breakpoint che potresti riuscire a risolvere senza troppi problemi. – alesplin

4

E 'molto probabilmente perché si sta gettando ogni volta. Prova questo:

(gdb) watch *0x12F5D58 

Un'altra opzione è che si ha troppi punti di controllo hardware insieme, in modo da gdb è costretto ad usare watchpoints software. Prova a controllare il numero di punti di controllo che avete utilizzando:

(gdb) info break 

e vedere se è possibile disattivare alcuni watchpoints.

+0

Gdb può davvero dereferenziare un intero letterale, senza bisogno di sapere quale tipo di dereferenziamento? Questa non è un'espressione C valida, almeno ... – unwind

+0

Sì, è possibile. Lo faccio tutto il tempo. –

+1

Con mia sorpresa (pensavo che GDB accettasse solo espressioni C) "watch * 0x12F5DF8" funziona, ma è lento come la versione precedente. –

1

Su x86 si ha la seguente limitazione: tutti i watchpoint possono contenere non più di quattro indirizzi di memoria, ciascun indirizzo di memoria può guardare per una parola di memoria - questo perché i watchpoint hardware (quelli veloci) utilizzano i registri di debug del processore , ne hai quattro, quindi quattro luoghi da tenere d'occhio.

+1

Ha già detto che aveva un solo punto di osservazione, vedere il quarto commento alla risposta di Nathan. –

5

Ho scoperto che guardare un grande buffer di caratteri era molto lento, mentre guardare un personaggio in quel buffer era molto veloce.

ad es.

static char buf[1024]; 
static char* buf_address = &buf; 

watch buf_address - estremamente lento.

watch *buf_address - molto veloce.