【问题标题】: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 下执行此操作?

【问题讨论】:

    标签: c++ visual-studio debugging


    【解决方案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。它甚至允许在读取位置时设置数据断点。

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

          【讨论】:

            猜你喜欢
            • 2017-02-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-05
            • 1970-01-01
            • 1970-01-01
            • 2015-05-10
            相关资源
            最近更新 更多