“!heap -flt -s xxxx”windbg命令中的不同列代表什么?

时间:2011-07-14 01:09:17

标签: debugging heap windbg

我一直在做一些关于高内存问题的工作,我在windbg中做了很多堆分析,我很好奇不同的列在“!heap -flt -s xxxx”命令中的含义。

我读了What do the 'size' numbers mean in the windbg !heap output?,我查看了我的“Windows Internals”一书,但我仍然有一堆问题。所以列和我的问题都在下面。

**HEAP_ENTRY** - What does this pointer really point to? How is it different than UserPtr?
**Size** - What does this size mean? How is it different than UserSize?
**Prev** - This just appears to be the negative offset to get to the previous heap entry. Still not sure exactly how it's used.
**Flags** - Is there any documentation on these flags?
**UserPtr** - What is the user pointer? In all cases I've seen it's always 8 bytes higher than the HEAP_ENTRY, but I don't really know what it points to.
**UserSize** - This appears to be the size of the actual allocation.
**state** - This just tells you what state of this heap entry is (free, busy, etc....)

Example:
HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
  0015eeb0 0044 0000  [07]   0015eeb8    00204 - (busy)

3 个答案:

答案 0 :(得分:19)

<强> HEAP_ENTRY 堆在连续的内存段中存储已分配的块,每个分配的块以8字节头开始,后跟实际分配的数据。 HEAP_ENTRY列是已分配块的标头开头的地址。

<强>尺寸 堆管理器处理8个字节的多个块。该列是分配的8字节块的数量。在您的示例中,0044表示该块占用0x220字节(0x44 * 8)。

<强>上一页 每8乘以一个以字节为单位的负偏移量到前一个堆块。

<强>标志 这是一个编码以下信息的位掩码

0x01 - HEAP_ENTRY_BUSY
0x02 - HEAP_ENTRY_EXTRA_PRESENT
0x04 - HEAP_ENTRY_FILL_PATTERN
0x08 - HEAP_ENTRY_VIRTUAL_ALLOC
0x10 - HEAP_ENTRY_LAST_ENTRY

<强> UserPtr 这是由HeapAlloc(由malloc / new调用的)函数返回给应用程序的指针。由于标题总是8个字节长,因此总是HEAP_ENTRY +8。

<强> UserSize 这是传递HeapAlloc函数的大小。

<强>状态 这是Flags列的解码,告诉条目是忙,释放,最后一段,......

请注意,在Windows 7/2008 R2中,堆默认情况下使用名为LFH(低碎片堆)的前端,该前端使用默认堆管理器来分配调度用户分配数据的块。对于这些堆,UserPtr和UserSize不会指向真实的用户数据。 !heap -s的输出显示哪些堆是LFH启用的。

答案 1 :(得分:3)

通过查看Windows调试工具帮助文件中的!heap文档和MSDN上的堆文档以及excerpt中的Advanced Windows Debugging,这是我能够做到的放在一起:

  • HEAP_ENTRY :指向堆内条目的指针。如您所见,有一个8字节的头,其中包含HEAP_ENTRY结构的数据。 HEAP_ENTRY结构的大小是8个字节,它定义了“堆粒度”大小。这用于确定......
  • SIZE :条目的粒度(即分配大小/ 8)
  • FLAGS :这些是在winbase.h中定义的,其解释位于MSDN链接中。
  • USERPTR :指向已分配(或已释放)对象的实际指针

答案 2 :(得分:0)

嗯,HEAP_ENTRY和UserPtr之间的主要区别在于,堆必须被索引,分配,填充元数据(如用户可用的分配长度)...否则,你怎么能释放( p)没有提供分配了多少字节的东西?两个大小字段的情况相同:一件事是索引堆的结构有多大,有一点是内存区域对用户有多大。

反过来,FLAGS基本上指定了已分配内存块的哪些属性,如果它已提交或仅保留,并且我猜,如果需要,内核使用它来重新排列或共享内存区域(但是,正如nithins指定的那样)在MSDN中记录。

PREV ptr用于跟踪所有已分配的区域,第一个指针存储在PEB结构中,因此用户空间和内核空间代码都知道已分配的堆池。