zoukankan      html  css  js  c++  java
  • 使用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_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage 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

  • 相关阅读:
    最长上升子序列
    盒子与小球之三
    盒子与小球之二
    《深入理解计算机网络》读后小记 2
    《深入理解计算机网络》读后小记 1
    想成为Java高手的25个学习目标
    POI中设置Excel单元格格式
    如何用jar命令对java工程进行打包
    【网络流】有源汇上下界最大流
    【网络流】网络流基本概念
  • 原文地址:https://www.cnblogs.com/organic/p/5005633.html
Copyright © 2011-2022 走看看