使用Windbg在XP下Heap追踪失败的原因
1、故事背景
最近同事的代码中碰到一个bug会导致奔溃的bug,从dump上看是由于某个对象的堆内存指针被释放了,但代码仍调用了该对象指针的虚函数,从而引起内存访问违法崩溃,由于该类被大量使用,无法直接定位到具体哪个类被提前释放了,从而打算开启堆页检查,跟踪该对象堆内存指针被释放的代码位置,从而揪出元凶。
由于此bug在win7的机器上不易重现,在xp sp3的机器上较容易重现,故准备在xp sp3的机器上开启堆页检查(DHP),跟踪该对象指针被释放的代码位置和时机,由于未从用过gflag进行堆页检查和调试,故先写了段小代码练练手:
用gflag开启堆页检查:
设好符号文件后祭出 Windbg 走起,崩溃触发后断下,输入 !heap -p -a ecx 指令一举揪出元凶,但现实却是如此的骨感:
004010d9 8b11 mov edx,dword ptr [ecx] ds:0023:0161cff0=???????? 0:000> !heap -p -a ecx ReadMemory error for address eeddccee Use `!address eeddccee' to check validity of the address.
注:此处 ecx = pCTest
"mov edx,dword ptr [ecx]"表示取虚表指针
Windbg提示的读取内存错误,且改地址的内容无法显示,查看下该内存地址属性:
0:000> !address ecx 015d0000 : 0161b000 - 000b5000 Type 00020000 MEM_PRIVATE Protect 00000001 PAGE_NOACCESS State 00001000 MEM_COMMIT Usage RegionUsagePageHeap Handle 015d1000
address命令正确的指示了该地址为私有堆内存,但该内存页不可访问。
难道是堆页开启不正确?检查注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options,确定已经正确的设置了,尝试其他多种设置,甚至换工具进行设置,但结依然如此。难道是机器问题?于是在win7 32位机器上重复上述过程,发现是可以正确的打印出堆内存指针被释放的栈回溯的:
但更换其他xp机器依然不能正确显示。百度搜索无果,仔细看glfag使用说明和各项设置文档也无果,最后去翻了翻 Windows 调试的权威书《软件调试》关于页堆的章节,并按照该书666页查找栈回溯数据库的方法查了下所有UST数据库的回溯记录,找到了"CTEST* pCTest = new CTEST(); "的栈回溯几率,即申请堆内存的记录,但始终未找到释放堆内存的记录。于是再次怀疑xp下的页堆并没有真正启动或启动是有问题的,于是检查下页堆启动情况:
惊现“ReadMemory error for address eeddccee”,且只展示一个Page Heap句柄了,剩下的未展示完全,但页堆明明白白的现实已经开启,也有了准页堆,但数据却显示不出来,说明数据可能被破坏,但测试代码如此简单,而且也被windbg第一时间断下,不可能去破坏数据,难道是Windbg读取有问题?于是再次对此疑问进行google,果然有个外国朋友也碰到了类似的问题,其在帖子中提出换成6.6.0007.5版即可解决,试了下果然在xp下顺利输出了用户态栈回溯。那么为什么高版本的Windbg会出现此问题呢?
我想起在查找UST数据结构的时候,发现和《软件调试》上写的不一致,当时疑惑了下没有在意,再次翻出来对比发现:
Win7下StackTraceDataBase结构
XP下StackTraceDataBase结构
Win7下的 _STACK_TRACE_DATABASE 结构和xp下并不完全相同,关键的 Buckets(栈回溯记录)的结构偏移改了,而且原xp下是个数组,但win7下却变成了链表,故猜测高版本的Windbg在xp下依然使用了win7下的某些数据结构,从而导致Windbg解析出了问题,不知道算不算微软的bug。
由于低版本的Windbg已经很难找到了,故这里也放出我找到的6.6.0007.5版:
Widnbg6.6.0007.5.exe
使用Windbg在XP下Heap追踪失败的原因的更多相关文章
- reggetvalue在xp下加载失败
在windows 32bit的xp下使用reggetvalue会提示,无法定位程序输入点reggetvalueW于动态链接库advapi32.dll(UNICODE).reggetvalueA也是无法 ...
- 在新建的python3环境下运行jupyter失败的原因
在deeplearning中再运行jupyter notebook就出现了错误: (deeplearning) userdeMBP:~ user$ jupyter notebook -bash: ju ...
- 在XP下安装PHP
最近,有许多朋友问我在WindowsXp下PHP的安装过程,正好最近我在自己的机器上成功的以模块化的方式安装了PHP4.23.既然这么多朋友需要,我就以最常见的IIS和Apache服务器为例,把PHP ...
- 在XP下基于VHD版XP 2003 win7制作的RAMOS心得
在XP下基于VHD版win7制作的RAMOS心得1.用DiskGenius创建1.85G的VHD固定磁盘文件,以win7prosen.vhd为例,然后进行分区格式化,格式化时启用NTFS压缩.2.为了 ...
- xp下删除windows7,无法删除windows7文件夹,无法删除windows7文件,双系统卸载,取得文件权限
http://blog.csdn.net/lanmanck/article/details/5722050 ---------------------------------------------- ...
- 转:windows xp下如何安装SQL server2000企业版
SQL2000企业版本 适用于WIN 2000 Server系统和Windows 2003系统,Windows XP一般装不了需要选用个人版或开发板.但是企业版也可以安装在xp系统下.这里介绍一个XP ...
- windows下redis启动失败提示maxheap flag
windows下redis启动失败 D:\redis>redis-server.exe redis.conf [] Oct ::39.789 # The Windows version of R ...
- 如何让VS2012编写的程序在XP下运行
Win32主程序需要以下设置 第一步:在工程属性General设置 第二步:在C/C++ Code Generation 设置 第三步:SubSystem 和 Minimum Required Ve ...
- xp 下查看进程指令
xp 下快速查看进程及关联 exe 的指令,刚发现,还没有测试 win7 和 win10 支持不支持. wmic process where creationclassname="win32 ...
随机推荐
- jQuery post数据至ashx
今天给大家分享一个小功能,在jQuery环境中,Post data to ashx进行数据交互. 参考下面代码示例: $.ajax({ url: '<%= ResolveUrl("~/ ...
- 使用toggle()方法进行显示隐藏
这是一个示例: <html> <head> <script type="text/javascript" src="http://keley ...
- MVC5+EF6+AutoMapper+Bootstrap打造在线博客(1.0)
目的:MVC5+EF6开发一个高并发.分布式的在线博客,等开发完成以后再用.net core,mysql重新开发,部署到linux系统上,这一系列就算完结,经验不足,大家一起讨论进步,源代码下载QQ群 ...
- php实现设计模式之 备忘录模式
<?php /*备忘录模式:在不破坏封装的前提下,获取对象的内部状态,并且在对象外保存该状态.这样就可以将该对象恢复到保存之前的状态(行为模式) * * 发起人:记录当前时刻的内部状态,负责定义 ...
- 服务器判断http是否中断
一般来说,只需要send或者recv一下,如果结果为零,则为掉线. 1.当recv返回值为0是表示对方已经正常(MSDN说是完美的)的断开连接.2.当recv返回SOCKET_ERROR时,说明对方已 ...
- GJM :SqlServer语言学习笔记
----------------------------SqlServer RDBMS 关系型数据库管理系统 Row/Record 行 Colimn/Attribute 列 Field/Cell 字段 ...
- GJM : 游戏程序员的学习之路
原文作者:miloyip 原帖地址:http://gad.qq.com/article/detail/7180681 原帖备注:版权所有,禁止匿名转载:禁止商业使用:禁止个人使用. 腾讯前端技术总监 ...
- SpringMVC处理客户端请求的过程
SpringMVC处理客户端请求的过程 以程序部署在Tomcat上为例,网站程序使用SpringMVC框架开发. 1.客户端发起一个访问网站的请求(如: localhost:8080/index). ...
- 弄一个ajax笔记方便查询-$.ajax()
$.ajax()是所有ajax方法中最底层的方法,所有其他方法都是基于$.ajax()方法的封装.这个方法只有一个参数,传递一个各个功能键值对的对象. $.ajax()方法对象参数表: 参数 类型 说 ...
- HTML5中使用图片传递密文
上面的两张图片中,你能看出有什么不同吗? 右图使用 html5 canvas api 中的 getImageData 和 putImageData 函数嵌入了一段文字. 道理很简单,getImageD ...