2012-06-12 15 views
24

Sto eseguendo il debug di un programma in gdb e voglio che il programma si fermi quando si accede alla regione di memoria da 0x08049000 a 0x0804a000. Quando provo a impostare manualmente i breakpoint di memoria, gdb sembra non supportare più di due posizioni alla volta.Guarda un intervallo di memoria in gdb?

(gdb) awatch *0x08049000 
Hardware access (read/write) watchpoint 1: *0x08049000 
(gdb) awatch *0x08049001 
Hardware access (read/write) watchpoint 2: *0x08049001 
(gdb) awatch *0x08049002 
Hardware access (read/write) watchpoint 3: *0x08049002 
(gdb) run 
Starting program: /home/iblue/git/some-code/some-executable 
Warning: 
Could not insert hardware watchpoint 3. 
Could not insert hardware breakpoints: 
You may have requested too many hardware breakpoints/watchpoints. 

C'è già una domanda in cui questo è stato chiesto e la risposta è stata, che può essere possibile fare questo con valgrind. Sfortunatamente la risposta non contiene alcun esempio o riferimento al manuale di valgrind, quindi non era molto illuminante: How can gdb be used to watch for any changes in an entire region of memory?

Quindi: Come posso guardare l'intera area di memoria?

+0

Fatto interessante: i punti di interruzione PowerPC ha spaziato (?) Ma non watchpoints: http://stackoverflow.com/questions/ 13410941/set-breakpoint-on-ogni-line-in-gdb/31658056 # 31658056 –

+0

x86 supporta gamme di piccoli orologi fino a 8 byte: https://en.wikipedia.org/wiki/X86_debug_register –

risposta

23

Se si utilizza GDB 7.4 insieme a Valgrind 3.7.0, allora si hawatchpoint hardware "emulati" illimitati.

avviare il programma sotto Valgrind, dando gli argomenti --vgdb=full --vgdb-error=0 quindi utilizzare GDB di connettersi ad esso (target remote | vgdb). Quindi è possibile ad es. watch o awatch o rwatch un intervallo di memoria facendo rwatch (char[100]) *0x5180040

Vedere the Valgrind user manual on gdb integration per ulteriori dettagli

+2

Dopo aver trascorso la parte migliore del giorno giocherellando con 'mprotect' e abusando dei gestori di SIGSEV per interrompere l'accesso alla memoria, ho provato questo. Funziona perfettamente. Mi hai salvato la giornata. Grazie! – iblue

+0

Sì, anche +1. Sono stato a caccia di una funzione come questa per mesi. – Crashworks

+0

Quindi, come si determina l'indirizzo heap per il processo avviato da valgrind? Solitamente lo faccio tramite */proc/[pid]/maps * ma quando avvio python tramite questo comando valgrind, il file maps non ha una voce identificata da ** [heap] ** come sono abituato a trovare . –

10

La caratteristica che rileva quando un indirizzo di memoria è cambiata è chiamato a hardware breakpoint, ed è in realtà una funzione della CPU — un registro interno il controller di memoria che rileva quando si accede un indirizzo specifico, e genera un interrupt pausa debugger. Purtroppo the x86 architectureonly has four such registers ed è per questo che sei limitato nel numero di punti di interruzione della memoria che puoi impostare.

Ecco perché è necessario utilizzare qualcosa come valgrind; se vuoi vedere un'intera regione, devi farlo usando un software che simula i modelli di accesso alla memoria. Non so se valgrind supporti effettivamente la visualizzazione di interi intervalli di memoria, comunque. Potrebbe essere necessario ripararlo da soli. Modifica VALGRIND_MAKE_MEM_NOACCESS() per lanciare un punto di interruzione, ma poi consentire al programma di continuare, forse.