2009-08-11 4 views
12

El depurador DEC Tru64 UNIX tenía una característica (llamada "puntos de observación para monitorear variables") que miraba una ubicación de memoria (o rango de direcciones) para leer o escribir actividad y cuando detectaba tal actividad rompería el programa para que pudiera investigar por qué. Ver para más detalles:Interrupción automática cuando el contenido de una ubicación de memoria cambia o se lee

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

¿Hay alguna manera de hacer este tipo de cosas en el depurador VisualStudio? ¿O hay un complemento o alguna otra herramienta que pueda hacer esto en Windows?

Respuesta

19

Sí, puedes hacerlo en Visual Studio. Puede crear un "Punto de interrupción de datos nuevos" debajo del menú de depuración mientras está roto en un programa en ejecución. Luego especifica la dirección a mirar y la cantidad de bytes.

Esto solo funciona para cambiar el valor. No sé cómo ver el acceso de lectura. Sin embargo, es una pregunta muy común querer saber dónde se cambió un valor. Me parece que no quiero saber quién lee un valor con tanta frecuencia.

+2

¡Eso es lo que estaba buscando, gracias! –

+0

El elemento de menú solo está habilitado mientras el depurador está activo. Pensé por un tiempo que había sido desactivado en Express. – Artfunkel

0

Sí, los puntos de interrupción de datos pueden detectar escrituras. Sin embargo, no sé si es posible verificar la lectura. No creo que x86 tenga soporte nativo para eso.

6

Visual Studio allows to set puntos de interrupción en la ubicación de memoria de solo 4 bytes de longitud (en la versión de Windows de 32 bits). Para la captura de acceso a memoria (lectura o escritura), puede utilizar la siguiente clase:

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 el modo de acceso en las páginas de memoria seleccionadas. El tamaño de página es igual a 4096 bytes en sistemas de 32 bits. Se lanzarán excepciones en cada acceso a la memoria protegida. Esta clase tiene un uso limitado solo para áreas de memoria grandes, pero espero que pueda ser útil.

Podría ser utilizado de la siguiente manera:

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

Esto es excesivo para lo que estaba buscando, pero lo archivaré para un día desafortunado cuando tenga un problema realmente desagradable que atrapar. –

+0

Esto es increíble para trabajar alrededor del límite de 4 puntos de ruptura – paulm

1

Puede utilizar WINDBG y establecer un punto de interrupción ba en la dirección deseada

0

recomiendo the hwbreak project. Incluso permite establecer un punto de interrupción de datos cuando se lee una ubicación.

Lo modifiqué para crear solo un hilo, y para reutilizar ese hilo para todos los puntos de interrupción de datos, pero eso era solo por eficiencia.

Cuestiones relacionadas