当内存位置的内容改变或被读取时自动中断

Posted

技术标签:

【中文标题】当内存位置的内容改变或被读取时自动中断【英文标题】:Automatic break when contents of a memory location changes or is read 【发布时间】:2009-08-11 15:40:57 【问题描述】:

旧的 DEC Tru64 UNIX 调试器具有一项功能(称为“监视变量的监视点”),它可以监视内存位置(或地址范围)的读取或写入活动,并且当它检测到此类活动时会破坏程序,因此您可以调查原因。详情见:

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

有没有办法在 VisualStudio 调试器中做这种事情?或者是否有插件或其他工具可以在 Windows 下执行此操作?

【问题讨论】:

【参考方案1】:

是的,您可以在 Visual Studio 中执行此操作。当您在运行的程序中中断时,您可以在调试菜单下创建一个“新数据断点”。然后指定要监视的地址和字节数。

这仅适用于更改值。我不知道如何监视读取访问。但是,想知道值在哪里更改是一个非常常见的问题。我发现我不想知道谁经常读取一个值。

【讨论】:

该菜单项仅在调试器处于活动状态时启用。我想了一会儿,它在 Express 中被禁用了。【参考方案2】:

Visual Studio allows to set 内存位置的断点长度仅为 4 字节(在 32 位 Windows 版本上)。要捕获内存访问(读取或写入),您可以使用以下类:

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

它改变了选定内存页面的访问模式。在 32 位系统上,页面大小等于 4096 字节。每次访问受保护的内存都会引发异常。这个类仅限于使用大内存区域,但我希望它可以有所帮助。

可以通过以下方式使用:

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

【讨论】:

【参考方案3】:

您可以使用WINDBG并在所需地址上设置一个断点

【讨论】:

【参考方案4】:

是的,数据断点可以检测写入。不过,不知道是否可以检查读取。我不相信 x86 对此有本机支持。

【讨论】:

【参考方案5】:

我推荐the hwbreak project。它甚至允许在读取位置时设置数据断点。

我将其修改为只创建一个线程,并将该线程重用于所有数据断点,但这只是为了提高效率。

【讨论】:

以上是关于当内存位置的内容改变或被读取时自动中断的主要内容,如果未能解决你的问题,请参考以下文章

Java 循环读取文件导致内存溢出!

stm32外部中断引脚模式改变

android内存管理

仅读取共享内存时的互斥锁

从 WebAPI 调用的正文中读取 XML 内容在开始时被中断

动态调整视图大小(拖动运动)时自动布局约束中断