【问题标题】:How to interpret the result of !heap -l from Windbg如何从 Windbg 解释 !heap -l 的结果
【发布时间】:2018-10-31 07:17:36
【问题描述】:

我有一个来自我怀疑存在内存泄漏的进程的 3.5Gb 转储文件。我使用 Windbg 分析转储文件,我使用的特定命令是 !heap -l (用于泄漏检测)。结果表明,检测到 807258 个潜在的不可达块。但是,我不知道如何使用分析结果。报告格式如下:

条目 |用户 |堆 |细分 |尺寸 |上一页尺寸 |未使用 |标志

00000000002e4190 | 00000000002e41a0 | 0000000000260000 | 0000000000260000 | 210 | 60 | 10 |忙

......(其余 807258 行)

我的理解是堆列告诉您泄漏来自哪个堆,但是 Entry 和 User 代表什么?我在微软的在线文档中找不到任何解释。有人可以帮我理解这些列的含义吗?

【问题讨论】:

    标签: debugging memory-leaks windbg


    【解决方案1】:

    Entry 是该堆分配的HEAP_ENTRY 的地址。它没有记录,但看起来 something like this

    您可以使用dt nt!_HEAP_ENTRY 查看它在系统上的外观,甚至可以使用dt nt!_HEAP_ENTRY 00000000002e4190 查看特定的堆条目。

    这是nt!_HEAP_ENTRY 在我的系统上的布局:

    0:007> dt nt!_HEAP_ENTRY
    ntdll!_HEAP_ENTRY
       +0x000 UnpackedEntry    : _HEAP_UNPACKED_ENTRY
       +0x000 PreviousBlockPrivateData : Ptr64 Void
       +0x008 Size             : Uint2B
       +0x00a Flags            : UChar
       +0x00b SmallTagIndex    : UChar
       +0x008 SubSegmentCode   : Uint4B
       +0x00c PreviousSize     : Uint2B
       +0x00e SegmentOffset    : UChar
       +0x00e LFHFlags         : UChar
       +0x00f UnusedBytes      : UChar
       +0x008 CompactHeader    : Uint8B
       +0x000 ExtendedEntry    : _HEAP_EXTENDED_ENTRY
       +0x000 Reserved         : Ptr64 Void
       +0x008 FunctionIndex    : Uint2B
       +0x00a ContextValue     : Uint2B
       +0x008 InterceptorValue : Uint4B
       +0x00c UnusedBytesLength : Uint2B
       +0x00e EntryOffset      : UChar
       +0x00f ExtendedBlockSignature : UChar
       +0x000 ReservedForAlignment : Ptr64 Void
       +0x008 Code1            : Uint4B
       +0x00c Code2            : Uint2B
       +0x00e Code3            : UChar
       +0x00f Code4            : UChar
       +0x00c Code234          : Uint4B
       +0x008 AgregateCode     : Uint8B
    

    User 只是RtlAllocateHeap()HeapAlloc() 返回的分配的开始。

    通常等于Entry 地址加上sizeof(_HEAP_ENTRY)

    【讨论】:

    • 感谢您的回答。另外,这里的剂量大小是什么意思?这是 RtlAllocateHeap() 或 HeapAlloc() 返回的实际分配的大小吗?
    • @OptimusPrime Size 字段直接取自nt!_HEAP_ENTRY。不一定是请求的大小,而是堆管理器决定返回的分配大小,包括nt!_HEAP_ENTRY 本身占用的空间。这为堆提供了一些摆动空间,可以找到大小接近但不一定准确的空闲条目。
    • (续)它还允许进行一些优化,例如将特定大小的所有条目保存在一起,就像low-fragmentation heap 的情况一样。 (注意:从nt!_HEAP_ENTRY 中提取Size 字段的棘手之处在于它是经过编码的。参见this answer
    • 当我使用 !heap -l 查找泄漏时,返回的堆条目之一是堆 0000000000270000 上的 00000000002e73d0。但是当我使用 !heap -a 0000000000270000 查找此堆上的所有堆条目时,这条目未列出。你知道为什么泄露的条目在那里没有显示吗?
    • @OptimusPrime 只是一个猜测,但如果!heap -l 在标志列中显示LFH(这是一个低碎片堆条目),那么!heap -a 将不会打印有关该条目的任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 2014-07-10
    • 2017-05-02
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多