2009-08-11 3 views
12

Der alte DEC Tru64 UNIX-Debugger hatte eine Funktion ("Watchpoints zur Überwachung von Variablen"), die einen Speicherbereich (oder Adressbereich) für Lese- oder Schreibaktivitäten überwacht und wenn es eine solche Aktivität entdeckt, würde das Programm kaputt gehen, so dass Sie nachsehen könnten, warum. Details siehe:Automatische Unterbrechung, wenn sich der Inhalt eines Speicherplatzes ändert oder gelesen wird

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

Gibt es eine Möglichkeit, diese Art von Dingen in dem Visual Studio-Debugger zu tun? Oder gibt es ein Add-on oder ein anderes Tool, das dies unter Windows tun kann?

Antwort

19

Ja, Sie können dies in Visual Studio tun. Sie können einen "Neuen Datenhaltepunkt" im Debug-Menü erstellen, während Sie in einem laufenden Programm unterbrochen sind. Sie geben dann die zu überwachende Adresse und die Anzahl der Bytes an.

Dies funktioniert nur zum Ändern des Wertes. Ich weiß nicht, wie ich auf Lesezugriff achten soll. Es ist jedoch eine sehr häufige Frage zu wissen, wo sich ein Wert geändert hat. Ich finde, dass ich nicht wissen will, wer einen Wert so oft liest.

+2

Das habe ich gesucht, danke! –

+0

Der Menüeintrag ist nur aktiviert, während der Debugger aktiv ist. Ich dachte eine Weile, dass es in Express deaktiviert wurde. – Artfunkel

0

Ja, Datenhaltepunkte können Schreibvorgänge erkennen. Ich weiß nicht, ob es möglich ist, nachlesen zu lassen. Ich glaube nicht, dass x86 native Unterstützung dafür hat.

6

Visual Studio allows to set Haltepunkte auf Speicherplatz nur 4 Byte Länge (auf 32-Bit-Windows-Version). Um Speicherzugriff zu fangen (Lesen oder Schreiben) können Sie die folgende Klasse verwenden:

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; 
}; 

Es ändert Zugriffsmodus auf ausgewählte Speicherseiten. Die Seitengröße entspricht 4096 Byte auf 32-Bit-Systemen. Bei jedem Zugriff auf geschützten Speicher wird eine Ausnahme ausgelöst. Diese Klasse ist nur auf große Speicherbereiche beschränkt, aber ich hoffe, sie kann hilfreich sein.

Es ist in der folgenden Art und Weise verwendet werden könnten:

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

Das ist Overkill für das, was ich gesucht habe, aber ich werde es für einen unglücklichen Tag ablegen, wenn ich ein wirklich unangenehmes Problem habe. –

+0

Dies ist großartig, um die Grenze von 4 Punkten zu umgehen – paulm

1

Sie können WINDBG verwenden und einen ba Haltepunkt auf die gewünschte Adresse

0

Ich empfehle the hwbreak project gesetzt. Es kann sogar ein Datenhaltepunkt gesetzt werden, wenn ein Standort gelesen wird.

Ich änderte es, um nur einen Thread zu erstellen, und diesen Thread für alle Datenhaltepunkte wiederzuverwenden, aber das war nur für die Effizienz.

Verwandte Themen