GFlags调试堆中野指针

我个人觉得写代码最悲哀的就是,程序的出错结果往往出人意料,并不在自己预期的错误列表中,其中堆中的野指针就是一个很隐蔽的问题。记得之前写了一个模块,后来因为功能升级,而修改了部分接口,等到运行的时候,老是会出现堆中野指针访问的问题。但是当时我万万没有猜想到是这个问题,因为我根本没有修改任何与内存分配的代码啊?后来,只好根据调试时候的错误对话框,去Google了一把,最终使用了GFlags才使得VC自动断点到出问题的代码。因此,就在这里将GFlags的使用Mark一下。


  如果你是C++程序员,如果你写过一个很复杂的程序,如果你经常碰到莫名其妙的崩溃问题。那么你就有可能遭遇了野指针。如果你比较细心,注意了Debug Output输出窗口的话,那么你就有可能注意到这样一行提示:
   HEAP:   Free   Heap   block   xxxxxxxx modified   at   xxxxxxxx  after   it   was   freed

Gflags是随着微软Debugging tools for windows一起发布的工具。使用Gflags就能让系统对Heap的分配,访问做一些检查,尽早的发现问题。Gflags的具体用法请参考微软的帮助文档,就不罗嗦了:
  Run: gflags -p /enable test.exe /full /unaligned

GFlags是Windows debug tools 工具包下的一个工具,在Windows 2000的Resource Kit中也可以找得到。用来设置一些调试属性,总体上分为3个级别System,Kernel和Image File。我们设置好Path环境变量,将其指向Debug tools工具的目录下。
输入如下命令行:
  gflags /p App.exe /full
或者
  pageheap app.exe /full
该命令行会在注册表里设置一些调试参数,使内存在使用的时候加入了保护机制,所以一旦内存写越界,或者发生野指针的问题,都会导致一个中断。由此,你就可以确定问题到底出在哪里了。

PS:实际使用中,将这个GFlags拷贝到所调试的EXE同级目录下,按照上面的命令行,进行设置即可,但是要注意在调试完了以后,要立即修改回来,因为注册表中相关表项并没有被删除,所以程序仍旧处于调试状态中,会影响程序的运行。

PS2:
Heap corruption detected:
  after normal block(#xxx) at 0Xxxxxxxxx crt detected that the application wrote to menory after end of heap buffer.

这是典型的内存溢出错误,常在内存的delete处发生,而且一般在debug版本中可能出现,release版本中可能并不报错。
出现这个错误的原因一般都是操作new申请的内存溢出,因为在C++中,如果用new分配一段内存,操作的时候改变了该部分的大小,在delete时就会出错。比如说如下部分:
char* p = new char[5];
strcpy(p,"aaaaa");
delete[] p;
这段代码就会出错,因为申请了一个size为5的内存,但是strcpy过去了一个size为6的字符串,因此破坏了这个指针,运行debug版本的时候就会出现先前的错误,但是在release版本中,系统是不会检查这个错误的,除非溢出导致程序的不正常,否则是不会报错的。因此,在程序中进行内存分配的时候一定要注意不能越界。

你可能感兴趣的:(flag)