zoukankan      html  css  js  c++  java
  • Windbg学习19(!heap)

    以下以windbg启动calc为调试结果:

    1!heap

    !heap 扩展显示堆使用信息,控制堆管理器中的断点,检测泄露的堆块,搜索堆块或者显示页堆(page heap)信息。

    !heap -h列出当前进程的所有堆:

    0:000> !heap -h
    Index   Address  Name      Debugging options enabled
      1:   000a0000 
        Segment at 000a0000 to 001a0000 (00003000 bytes committed)
      2:   001a0000 
        Segment at 001a0000 to 001b0000 (00006000 bytes committed)
      3:   001b0000 
        Segment at 001b0000 to 001c0000 (00003000 bytes committed)


    !heap -v可以观察堆的分配粒度和解除提交阈值:

    0:000> !heap 000a0000 -v
    Index   Address  Name      Debugging options enabled
      1:   000a0000 
        Segment at 000a0000 to 001a0000 (00003000 bytes committed)
        Flags:                50000062
        ForceFlags:           40000060
        Granularity:          8 bytes
        Segment Reserve:      00100000
        Segment Commit:       00002000
        DeCommit Block Thres: 00000200
        DeCommit Total Thres: 00002000
        Total Free Size:      000000d1
        Max. Allocation Size: 7ffdefff
        Lock Variable at:     000a0608
        Next TagIndex:        0000
        Maximum TagIndex:     0000
        Tag Entries:          00000000
        PsuedoTag Entries:    00000000
        Virtual Alloc List:   000a0050
        UCR FreeList:        000a0598
        FreeList Usage:      00000000 00000000 00000000 00000000
        FreeList[ 00 ] at 000a0178: 000a2980 . 000a2980   (1 block )

    Segment at 000a0000 to 001a0000 (00003000 bytes committed)指明堆的内存范围和提交字节数
    Granularity: 8 bytes指明堆块分配粒度

    由于堆管理器使用HEAP结构来记录和维护堆的管理信息,因此我们把这个结构称为堆的管理结构,因为这个结构总是在每个堆的开始处,因此有时也被称为堆的头结构

    下面显示了_HEAP的结构:

    :000> dt ntdll!_HEAP 000a0000 
       +0x000 Entry            : _HEAP_ENTRY
       +0x008 Signature        : 0xeeffeeff
       +0x00c Flags            : 0x50000062
       +0x010 ForceFlags       : 0x40000060
       +0x014 VirtualMemoryThreshold : 0xfe00
       +0x018 SegmentReserve   : 0x100000
       +0x01c SegmentCommit    : 0x2000
       +0x020 DeCommitFreeBlockThreshold : 0x200
       +0x024 DeCommitTotalFreeThreshold : 0x2000
       +0x028 TotalFreeSize    : 0xd1
       +0x02c MaximumAllocationSize : 0x7ffdefff
       +0x030 ProcessHeapsListIndex : 1
       +0x032 HeaderValidateLength : 0x608
       +0x034 HeaderValidateCopy : (null) 
       +0x038 NextAvailableTagIndex : 0
       +0x03a MaximumTagIndex  : 0
       +0x03c TagEntries       : (null) 
       +0x040 UCRSegments      : (null) 
       +0x044 UnusedUnCommittedRanges : 0x000a0598 _HEAP_UNCOMMMTTED_RANGE
       +0x048 AlignRound       : 0x17
       +0x04c AlignMask        : 0xfffffff8
       +0x050 VirtualAllocdBlocks : _LIST_ENTRY [ 0xa0050 - 0xa0050 ]
       +0x058 Segments         : [64] 0x000a0640 _HEAP_SEGMENT
       +0x158 u                : __unnamed
       +0x168 u2               : __unnamed
       +0x16a AllocatorBackTraceIndex : 0
       +0x16c NonDedicatedListLength : 1
       +0x170 LargeBlocksIndex : (null) 
       +0x174 PseudoTagEntries : (null) 
       +0x178 FreeLists        : [128] _LIST_ENTRY [ 0xa2980 - 0xa2980 ]
       +0x578 LockVariable     : 0x000a0608 _HEAP_LOCK
       +0x57c CommitRoutine    : (null) 
       +0x580 FrontEndHeap     : 0x000a0688 
       +0x584 FrontHeapLockCount : 0
       +0x586 FrontEndHeapType : 0x1 ''
       +0x587 LastSegmentIndex : 0 ''

    Segments字段用来记录堆中包含的所有段,它是一个数组,每个元素都指向一个HEAP_SEGMENT结构的指针,

       +0x058 Segments         : [64] 0x000a0640 _HEAP_SEGMENT
    

    LastSegmentIndex的值加1就是段的总个数:

     +0x587 LastSegmentIndex : 0 ''

    说明就一个段:

    0:000> dt _HEAP_SEGMENT  0x000a0640 
    ntdll!_HEAP_SEGMENT
       +0x000 Entry            : _HEAP_ENTRY
       +0x008 Signature        : 0xffeeffee
       +0x00c Flags            : 0
       +0x010 Heap             : 0x000a0000 _HEAP
       +0x014 LargestUnCommittedRange : 0xfd000
       +0x018 BaseAddress      : 0x000a0000 
       +0x01c NumberOfPages    : 0x100
       +0x020 FirstEntry       : 0x000a0680 _HEAP_ENTRY//第一个堆块
       +0x024 LastValidEntry   : 0x001a0000 _HEAP_ENTRY
       +0x028 NumberOfUnCommittedPages : 0xfd
       +0x02c NumberOfUnCommittedRanges : 1
       +0x030 UnCommittedRanges : 0x000a0588 _HEAP_UNCOMMMTTED_RANGE
       +0x034 AllocatorBackTraceIndex : 0
       +0x036 Reserved         : 0
       +0x038 LastEntryInSegment : 0x000a2978 _HEAP_ENTRY//最后一个堆块


     堆管理器使用_HEAP_ENTRY来描述每个堆块:

    0:000> dt _HEAP_ENTRY 0x000a0680 
    ntdll!_HEAP_ENTRY
       +0x000 Size             : 0x303//堆块的大小,以分配粒度为单位
       +0x002 PreviousSize     : 8//前一个堆块的大小
       +0x000 SubSegmentCode   : 0x00080303 
       +0x004 SmallTagIndex    : 0x60 '`'
       +0x005 Flags            : 0x7 ''//标志
       +0x006 UnusedBytes      : 0x18 ''//因为补齐而多分配的字节数
       +0x007 SegmentIndex     : 0 ''//这个堆块所在段的序号

    其中Flags字段代表堆块的状态,其值是下列标志位的组合

    标志 含义
    HEAP_ENTRY_BUSY 01 该块处于占用状态
    HEAP_ENTRY_EXTRA_PRESENT 02 该块存在额外的描述
    HEAP_ENTRY_FILL_PATTERN 04 使用固定模式填充堆块
    HEAP_ENTRY_VIRTUAL_ALLOC 08 虚拟分配
    HEAP_ENTRY_LAST_ENTRY 0X10 这是该段的最后一个块

    _HEAP_ENTRY的长度固定为8字节长,位于堆块起始处,其后便是堆块的用户数据,也就是说,把HeapAlloc函数

    返回的地址减去8,就是这个堆块的_HEAP_ENTRY结构的地址



     



     

  • 相关阅读:
    docker初次体验-管理MySQL+tomcat镜像
    使用Eclipse可以方便的统计工程或文件的代码行数,
    This Android SDK requires Android Developer Toolkit version 17.0.0 or above. Current version is 10.0.0.v201102162101-104271. Please update ADT to the latest version.
    vim乱码问题
    文件上传和下载
    Freemaker的了解
    find命令
    shell文件安全与权限 笔记
    linux java环境配置
    linux redhat下oracle11G安装
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693510.html
Copyright © 2011-2022 走看看