2009-08-11 5 views
12

Il vecchio debugger di DEC Tru64 UNIX aveva una funzione (chiamata "watchpoint per monitorare le variabili") che guardava una posizione di memoria (o un intervallo di indirizzi) per attività di lettura o scrittura e quando ha rilevato tale attività, avrebbe interrotto il programma in modo da poterne verificare il motivo. Vedere per maggiori dettagli:Interruzione automatica quando il contenuto di una posizione di memoria cambia o viene letto

http://h30097.www3.hp.com/docs/base_doc/DOCUMENTATION/V50_HTML/ARH9QATE/DOCU_009.HTM

Esiste un modo per fare questo genere di cose nel debugger VisualStudio? O c'è un add-on o qualche altro strumento che può farlo sotto Windows?

risposta

19

Sì, puoi farlo nello studio visivo. È possibile creare un "Nuovo punto di interruzione dei dati" nel menu di debug mentre si è interrotti in un programma in esecuzione. Quindi si specifica l'indirizzo da guardare e il numero di byte.

Questo funziona solo per la modifica del valore. Non so come guardare per l'accesso in lettura. Tuttavia è una domanda molto comune voler sapere dove viene cambiato un valore. Trovo che non voglio sapere chi legge un valore tanto spesso.

+2

Questo è quello che stavo cercando, grazie! –

+0

La voce di menu è abilitata solo mentre il debugger è attivo. Ho pensato per un po 'che fosse stato disabilitato in Express. – Artfunkel

0

Sì, i punti di interruzione dei dati possono rilevare le scritture. Non so se è possibile verificare la lettura, però. Non credo che x86 abbia supporto nativo per questo.

6

Visual Studio allows to set punti di interruzione nella posizione di memoria solo 4 byte di lunghezza (nella versione di Windows a 32 bit). Per accedere alla memoria (leggi o scrivi) puoi utilizzare la seguente classe:

struct protect_mem_t { 
    protect_mem_t(void* addr, size_t size) : addr(addr), size(size), is_protected(FALSE) { 
     protect(); 
    } 
    ~protect_mem_t() { release(); } 
    BOOL protect() { 
     if (!is_protected) { 
      // To catch only read access you should change PAGE_NOACCESS to PAGE_READONLY 
      is_protected = VirtualProtect(addr, size, PAGE_NOACCESS, &old_protect); 
     } 
     return is_protected; 
    } 
    BOOL release() { 
     if (is_protected) 
      is_protected = !VirtualProtect(addr, size, old_protect, &old_protect); 
     return !is_protected; 
    } 

protected: 
    void* addr; 
    size_t size; 
    BOOL is_protected; 
    DWORD old_protect; 
}; 

Cambia modalità di accesso nelle pagine di memoria selezionate. La dimensione della pagina è uguale a 4096 byte nei sistemi a 32 bit. Eccezione verrà generata su ogni accesso alla memoria protetta. Questa classe è limitata in uso solo a grandi aree di memoria, ma spero che possa essere utile.

Potrebbe essere utilizzato nel modo seguente:

// some_array should be aligned on PAGE_SIZE boundaries 
protect_mem_t guard(&some_array, PAGE_SIZE); 
+0

Questo è eccessivo per quello che stavo cercando, ma lo archiverò per un giorno sfortunato quando ho un problema davvero sgradevole da cogliere. –

+0

Questo è fantastico per lavorare intorno al limite di 4 punti di interruzione – paulm

1

È possibile utilizzare WINDBG e impostare un punto di interruzione ba sull'indirizzo desiderato

0

consiglio the hwbreak project. Permette anche di impostare un punto di interruzione dei dati quando viene letto un luogo.

L'ho modificato per creare solo un thread e riutilizzare quel thread per tutti i punti di interruzione dei dati, ma era solo per l'efficienza.

Problemi correlati