内存变量被覆盖的调试(数据断点调试)

关于c++ vs2008中数据断点的设置

http://blog.csdn.net/jphaoren/article/details/6270270

熟悉数据断点的设置,能提高调试效率。

简单看下,数据断点是怎么设置的。

  

一般来说,函数断点在下面几种情形下有用:

  1 例如调试一个网站程序,你通过分析网站的日志发现最有可能发生错误的函数,打开调试器并将调试器附加到程序上去,设置函数断点,重新执行网站……这样做的好处是,不用到处打开源文件去找出错的源代码行,调试器会自动打开源代码,并且在函数的入口处中断(岂不是很方便?)。

  2 例如你在阅读源代码的时候,通常在读到虚函数调用的时候,因为通常这种调用都是通过基类指针调用的,而你又一时半会不知道到底有哪个继承类的Overloading函数会被调用到,函数断点可以告诉你。

  3 或者一种特殊的情形,你想读一个程序的源代码,但就是找不到入口Main函数,例如.NET程序,那么直接在Visual Studio里面按F11就能帮你找到入口函数—这是函数断点的一个特殊情形。

  4 比如你在调试Web Service函数,设置函数断点也是一个快捷的调试方法,这个技巧跟技巧1类似。

 

 

数据断点

  注意,这个技巧仅对C++程序调试有效(或者说native程序),而且你只能在中断模式下才能设置数据断点,另外你还只能在本机设置数据断点。

  上一节的例子里,我们提到了,有的时候一个全局变量被修改了以后,你可能都找不到它是什么时候被修改的,于是夜已深,人已寐,你还在辛苦地调试到底是哪个鬼地方把这个变量的值修改了。F11, F10,……,SHIFT + F11,……,F5,靠,调过了,重来,F11,F10,……

  这种情况下,数据断点就很有用了,Visual Studio允许你在变量被修改的时候,中断程序的执行,是不是很酷?

  默认情况下,你是找不到数据断点这个菜单的,需要执行下面的步骤把它拉出来:

  1 打开你要调试的项目。

  2 点击Visual Studio菜单栏里面的“工具(Tools)”—“自定义(Customize…)”。然后在“自定义(Customize…)”窗口中选择“命令(Commands)”页签里面的“种类(Categories)”列表框里的“调试(Debug)”,找到“新数据断点(New Data Breakpoint)”,将它拖到菜单栏里面相应的位置。

  然后打开或者创建一个C++项目,我们以下面的源代码为例子:

#include "stdafx.h"



int g_Variable = 0;



int _tmain(int argc, _TCHAR* argv[])

{



       printf("Before modifying data breakpoints"n");



       g_Variable = 1;



       printf("After modifying data breakpoints"n");



       return 0;

}

我们现在要Visual Studio在更改g_Variable的时候中断程序的执行。

  1 单击F11,这样程序就会在_tmain函数里面中断了,我们也就有机会设置数据断点了。

  2 点击菜单里面的“新数据断点(New Data Breakpoint)”。注意,数据断点是通过监视内存地址某一段区域更改来实现的,因此你必须提供一个内存地址(或者说就是指针吧),这里g_Variable是一个整形变量,因此你需要使用“&g_Variable”的形式来创建一个数据断点,因为整形的 大小是4个字节,因此数据断点监视的区域是4个字节。 

图3 断点监视区域
 

  3 继续程序的执行,这时会弹出一个对话框,告诉你有一个内存地址的内容发生了变化(说明我们的数据断点生效了),这时代码行指向的是数据被修改的下一行代码。

图4 运行提示

  为什么数据断点只能在C++/C程序中才能设置?是因为托管代码有垃圾回收。而数据断点的执行原理应该是Windows内存管理里面的Guard Pages概念和VirtualProtectEx函数的实现。这个概念可以自己去查MSDN的内存管理方面的文档。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章