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追踪失败的原因的更多相关文章

  1. reggetvalue在xp下加载失败

    在windows 32bit的xp下使用reggetvalue会提示,无法定位程序输入点reggetvalueW于动态链接库advapi32.dll(UNICODE).reggetvalueA也是无法 ...

  2. 在新建的python3环境下运行jupyter失败的原因

    在deeplearning中再运行jupyter notebook就出现了错误: (deeplearning) userdeMBP:~ user$ jupyter notebook -bash: ju ...

  3. 在XP下安装PHP

    最近,有许多朋友问我在WindowsXp下PHP的安装过程,正好最近我在自己的机器上成功的以模块化的方式安装了PHP4.23.既然这么多朋友需要,我就以最常见的IIS和Apache服务器为例,把PHP ...

  4. 在XP下基于VHD版XP 2003 win7制作的RAMOS心得

    在XP下基于VHD版win7制作的RAMOS心得1.用DiskGenius创建1.85G的VHD固定磁盘文件,以win7prosen.vhd为例,然后进行分区格式化,格式化时启用NTFS压缩.2.为了 ...

  5. xp下删除windows7,无法删除windows7文件夹,无法删除windows7文件,双系统卸载,取得文件权限

    http://blog.csdn.net/lanmanck/article/details/5722050 ---------------------------------------------- ...

  6. 转:windows xp下如何安装SQL server2000企业版

    SQL2000企业版本 适用于WIN 2000 Server系统和Windows 2003系统,Windows XP一般装不了需要选用个人版或开发板.但是企业版也可以安装在xp系统下.这里介绍一个XP ...

  7. windows下redis启动失败提示maxheap flag

    windows下redis启动失败 D:\redis>redis-server.exe redis.conf [] Oct ::39.789 # The Windows version of R ...

  8. 如何让VS2012编写的程序在XP下运行

    Win32主程序需要以下设置 第一步:在工程属性General设置 第二步:在C/C++ Code Generation 设置 第三步:SubSystem 和  Minimum Required Ve ...

  9. xp 下查看进程指令

    xp 下快速查看进程及关联 exe 的指令,刚发现,还没有测试 win7 和 win10 支持不支持. wmic process where creationclassname="win32 ...

随机推荐

  1. [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [二] 基本使用

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 使用环境 Visual Studio 2015 or later .NET 4 ...

  2. JQuery的ajax

    JQuery-AJAX: jQuery load() 方法是简单但强大的 AJAX 方法. $(selector).load(URL,data,callback);(这三个参数可以随意设置几个) @ ...

  3. Windows 7 Python 3.5 及 django 1.8 的安装

    本文参考:http://www.runoob.com/django/django-first-app.html 1.下载 安装 python 3.5 可以自定义安装位置 ,勾选设置环境变量Path 默 ...

  4. eclipse里打开SWT项目找不到source/design的图形UI设计界面

    因为前天重新装了个新版的eclipse, 结果今天打开一个SWT的项目,突然找不到source/design的图形UI设计的两个切换按钮 我把SWT组件重新装了还是找不到.结果后来发现是因为重装ecl ...

  5. Java的关键字与标识符

    Java作为一门编程语言,与其他语言一样,有字符集.标识符.和关键字.变量.常量.语句等编程语言的基本要素. 1.关键字 abstract boolean break byte case catch ...

  6. Python学习基础知识概要

    1.输入输出 输出实例   1 2 print 'hello','world' hello world 输入实例   1 2 3 4 5 name = raw_input(); print " ...

  7. 推荐15款响应式的 jQuery Lightbox 插件

    利用现代 Web 技术,网络变得越来越轻巧与.模态框是突出展现内容的重要形式,能够让用户聚焦到重要的内容上去.在这个列表中,我们编制了15款响应式的 jQuery 灯箱库,这将有助于开发人员创建和设计 ...

  8. HTML5中使用图片传递密文

    上面的两张图片中,你能看出有什么不同吗? 右图使用 html5 canvas api 中的 getImageData 和 putImageData 函数嵌入了一段文字. 道理很简单,getImageD ...

  9. PHP预定义变量

    * PHP预定义 * 预定义变量 * $_GET - 接收客户端以请求类型为GET方法发送的数据内容 * $_POST - 接收客户端以请求类型为POST方法发送的数据内容 * $_REQUEST - ...

  10. AMD and CMD are dead之KMD.js依赖可视化工具发布

    使用 require("MyAapp.DepTree", function (DepTree) { DepTree(({ renderTo: "holder", ...