使用PageHeap.EXE或GFlags.EXE检查内存越界错误
必先利其器之一:使用PageHeap.EXE或GFlags.EXE检查内存越界错误
Article last modified on 2002-6-3
----------------------------------------------------------------
The information in this article applies to:
- Microsoft Visual C++, 32-bit Editions, version 6.0, SP5
----------------------------------------------------------------
我推荐使用PageHeap.Exe和Gflags.Exe,主要的原因还是因为当有人问内存越界的错误如何查出来的时候,国外的朋友经常会推荐这两个工具(highly recommend)。我用过之后,也觉得有些时候用用还是有好处的。
|
PageHeap.Exe将针对某个指定的应用程序启用Page Heap标志,从而自动监视所有的malloc、new和heapAlloc的内存分配,找出内存错误。 PageHeap.Exe的下载地点: 下面我们简单地给出PageHeap使用步骤: 第一步: 在命令行中运行PageHeap.Exe。如果你以前设置过启用Global Page Heap标志,那么你将看到一个列表,给出所有已经启用了的应用程序的名字,不含路径。 如下所示: C:/>pageheap pgh.exe enabled testSplit.exe enabled 第二步: 编译一个小程序,其中有如下代码: void main() { int m_len = 5; char *m_p = (char *)HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, m_len); m_p[m_len] = 0;
HeapFree (GetProcessHeap (),0, m_p); } Build出一个Debug版本。运行之,你看不到有任何异常的报告。 但其实m_p[m_len]=0这句话就是越界写了,因为只分配到了m_p[m_len-1]!这种情况就叫Dynamic memory overrun。用BoundsChecker是可以查到的。 这时,表面上看不出任何问题,但是一颗定时炸弹已经埋下了。 第三步: 在命令行中运行PageHeap /enable YourApplicationName.exe 0x01。 再运行一次不带参数的PageHeap,察看上面的命令是否生效。你的应用程序应该在启用的列表中。 注意:千万不要在YourApplication.Exe前面加上路径!! 0x01的含义在后面说明。 第四步: 再次运行你的程序。 你将会注意到在Output窗口的加载各种DLL之前,多了几句话: Loaded exports for 'C:/WINNT/System32/ntdll.dll' Page heap: process 0x57C created heap @ 00130000 (00230000, flags 0x1) Loaded 'C:/WINNT/system32/MFC42D.DLL', no matching symbolic information found. .. Loaded 'C:/WINNT/system32/MSVCP60D.DLL', no matching symbolic information found. Page heap: process 0x57C created heap @ 00470000 (00570000, flags 0x1) Loaded exports for 'C:/WINNT/system32/imm32.dll' 这就是Page Heap的监视机制在发挥作用!他告诉你你的堆00470000被创建出来了。 然后程序退出后,Output窗口有这么几句话表明一定有什么错误发生了: Page heap: block @ 0015AFF8 is corrupted (reason 10) Page heap: reason: corrupted suffix pattern Page heap: process 0x57C destroyed heap @ 00471000 (00570000) The thread 0x8A8 has exited with code 0 (0x0). 这说明在销毁堆00470000时遇到了麻烦,就是数据块0015AFF8被误用了,原因是误用了下标语法。看,说得多么清楚!也节省了许多翻来覆去查代码的工作! PageHeap的使用中有几点值得注意: 1:启用PageHeap不能够影响正在运行中的应用程序。如果你需要启用一些正在运行且不能重启的程序的PageHeap,那请运行PageHeap启用后,重新启动机器。 2:要想查看PageHeap把信息放到哪里了,请打开你的注册表,来到 /HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT /CurrentVersion/Image File Execution Options 你将会看到你的应用程序也在这个项下面。你的应用程序的GlobalFlag被设置为了0x02000000,PageHeapFlags被设置为了0x01。 3:PageHeap的原理是这样,它在已分配的内存的后面放上几个守护字节(Guard Bytes),再跟上一个标记为PAGE_NOACCESS的内存页。这样,已分配内存的后面如果被重写了,那么守护字节就会被改变,于是当内存被释放时,PageHeap就会引发一个AV(Access Violation)。大体上就是这样。所以只有最后释放这块问题内存时,才会有PageHeap的报告!这就是PageHeap的局限性吧。 参数0x01的含义: FLAGS hex value (0x...) has the following structure: B7-B0 Bit flags 1 - enable page heap 01 - enable page heap. If zero normal heap is used. In 99% of the cases you will want this to be set. 02 - collect stack traces (default on checked builds) 04 - minimize memory impact 08 - minimize randomly(1)/based on size range(0) 10 - catch backward overruns 看到了吗?你还可以设置参数为0x10,从而可以检查内存向前的越界写! Gflags.Exe是微软的Debugging Tools里面的工具。在Windows 2000的Resource Kit中也可以找得到。我们也可以用它来完成和PageHeap相同的任务。当然,Gflags.EXE还能做许许多多其他的事情。这里我们就不介绍了,总之物超所值。 具体的使用办法是: 1) 运行Gflags.Exe; 2) 你将看到一个对话框。在”Image File”的编辑框中写下你的应用程序的名字,如YourApp.Exe。注意不要路径! 3) 选择”Image File Options”的单选钮; 4) 这时,你会看到对话框的内容突然一变。选中“Place heap 5) 点击Apply按钮。 这样,就达到了PageHeap的效果。现在运行你的程序,overwrite你的堆,就应该生成一个AV了! (预知详情请收听微软KB:SAMPLE: PageHeap1.exe Finds Heap Corruption and Memory Errors (Q264471) 你可以按照这篇文档所指引的步骤学习如何使用PageHeap) |
使用PageHeap.EXE或GFlags.EXE检查内存越界错误的更多相关文章
- 使用PageHeap.EXE或GFlags.EXE检查内存越界错误 (转)
2011-05-27 20:19 290人阅读 评论(0) 收藏 举报 microsoftdebuggingstructureoutputimagefile 必先利其器之一:使用PageHeap.EX ...
- Windows下使用Gflags检查内存越界
环境:windows xp. vs2005 Gflags可用于查找内存越界的问题. 访问一块申请的内存时,当访问的地址超过申请的范围时,就发生了内存越界的问题. 编写测试程序MemoryOverflo ...
- HSV做通道分离是出现的Vector内存越界错误
vector<Mat> hsvSplit; //因为我们读取的是彩色图,直方图均衡化需要在HSV空间做 split(imgHSV, hsvSplit); equalizeHist(hsvS ...
- Windbg的gflags.exe -- Attach调试利器
有没有碰到过程序启动就因为异常直接crash?有没有碰到程序启动之后什么反应也没有?有没有碰到过程序启动之后去触发另一个进程失败?有没有碰到别人的程序调用了你的代码,出现问题以后,让你来调查,而你只有 ...
- Android Monkey 脚本编写与检查内存泄露
一.Monkey脚本编写 1.Monkey脚本格式 脚本优势: 简单快捷,不需要接触任何工具,只需要一个记事本文件 脚本缺点: 实现坐标.按键等基本操作的相应步骤,顺序脚本无逻辑性 脚本源码: \de ...
- 在64位windows下使用instsrv.exe和srvany.exe创建windows服务[转]
本文转自:https://www.iflym.com/index.php/computer-use/201205020001.html 在32位的windows下,包括windows7,windows ...
- 在64位windows下使用instsrv.exe和srvany.exe创建windows服务
在64位windows下使用instsrv.exe和srvany.exe创建windows服务 在32位的windows下,包括windows7,windows xp以及windows 2003, ...
- 【转】在64位windows下使用instsrv.exe和srvany.exe创建windows服务
本文转自:https://www.iflym.com/index.php/computer-use/201205020001.html 在32位的windows下,包括windows7,windows ...
- Arduino上“Collect2.exe: error: ld returned 5 exit status”错误的解决方法
1.运行环境 Windows xp; Arduino1.6.11 IDE. 2.问题 在Arduino编译时,经常出现如下的错误: collect2.exe: error: ld returned 5 ...
随机推荐
- 知识点1-2:ASP.NET MVC背景
1.发展阶段 CGI(公共网关接口)-->ASP(Active Server Pages,活动服务器页面)-->.NET 2. .NET平台 2002年初,微软发布了第一版.NET框架,这 ...
- Python中__init__方法介绍
本文介绍Python中__init__方法的意义. __init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的 初始化 .注意,这个名称的开始和结尾 ...
- getElementById的缩略
谁都知道document.getElementById这个方法写起来比较麻烦,所以有时候我们会使用jq或者自己写一个小函数去封装,但是我这次说的缩略不同于往常的函数封装 在以前,我做过很多这样的尝试, ...
- 怎样用HTML5 Canvas制作一个简单的游戏
原文连接: How To Make A Simple HTML5 Canvas Game 自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML ...
- log翻硬币
若果有一组硬币,(假定有十个),每一个硬币仅仅有两个面,正面用以表示.反面用零表示. 给定目标(初始状态)1111100000 正正正正正反反反反反 (目标状态) 1000011101 正反反反反 ...
- java 随机数的生成
生成10个不小于100000的6位数 public static void main(String[] args) { Random random = new Random(); for (int i ...
- uva 10837 - A Research Problem(欧拉功能+暴力)
题目链接:uva 10837 - A Research Problem 题目大意:给定一个phin.要求一个最小的n.欧拉函数n等于phin 解题思路:欧拉函数性质有,p为素数的话有phip=p−1; ...
- 使用代码辅助生成工具CodeSmith -- 生成NHibernate的映射文件
首先下载CodeSmith工具:在百度云中,在CodeSmith文件夹中. 安装,使用激活工具激活. 然后下载NHibernate模板,也是在百度云中,在CodeSmith文件夹中. 之后直接点击NH ...
- Sed常用实例总结
[Sed简介] sed是一个文件处理工具,本身是一个管道命令,主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等.sed以行为单位,一次处理一行内容,处理时,把当前处理的行存储在临时 ...
- HTML文档类型DTD与浏览器怪异模式
虽然在兼容IE6时候经常会注意到两个模式的区别,但是系统的理解起来,还没有认真总结过.看了一些网上的资料.结合自己的理解汇总了一下,放在这里备忘并分享给大家. 浏览器从服务端获取网页后会根据文档的DO ...