【问题标题】:In windbg, how do I get a heap header address from !heap -l results?在 windbg 中,如何从 !heap -l 结果中获取堆头地址?
【发布时间】:2010-03-23 20:42:12
【问题描述】:

我正在使用 windbg 的 !heap 命令,特别是用于检测内存泄漏的“-l”开关。

当 -l 确实检测到泄漏时,我在从其结果导航到泄漏源的堆栈跟踪时遇到问题。

这是 !heap -l 的结果的 sn-p。格式已更改,以使输出更具可读性。

0:066> !heap -l 在内存中搜索潜在的无法访问的繁忙块。

进入用户堆段
0324b500 0324b508 01580000 03230000
0324b520 0324b528 01580000 03230000

(为简单起见,省略了 Size、PrevSize、Unused 和 Flags 列。)

Windbg 的 !heap 文档告诉我将 dt _DPH_BLOCK_INFORMATION 与标头地址一起使用,然后将 dds 与块的 StackTrace 字段一起使用。但是 !heap -l 的输出没有指定标头地址!它只指定条目、用户、堆和段。我绞尽脑汁查看其他命令,但不知道如何从这些字段中获取标题地址。有人可以帮忙吗?

【问题讨论】:

    标签: windbg


    【解决方案1】:

    您是否使用 AppVerifier 或 Gflags 启用了所需的调试选项?仅当启用 pageheap 选项时,内存块才会具有 _DPH_BLOCK_INFORMATION,并且如果还启用了该选项,您将能够显示堆栈回溯。要显示块的堆栈跟踪,您可以使用!heap -p -a <block address>

    请注意,如果在应用程序退出时不使用 !heap -l 可能会显示大量误报。您也可以尝试 umdh(也包含在 Windows 调试工具中)或 DebugDiag。

    【讨论】:

    • 感谢您的回复!我知道我应该使用 !heap -p -a 来获取跟踪,但问题是我不知道如何从返回的信息中提取块地址 !heap -l (即、堆、用户、条目或段)。你知道怎么做吗?感谢 !heap -l 如果在退出时不使用会显示误报的警告。我没有意识到这一点。文档听起来好像它正在跟踪没有更多引用的内存。
    • 我也知道 UMDH 并且我喜欢它,但是,唉,我的应用程序对于它来说太大了。我最近被介绍给 DebugDiag,它就像一个魅力。但是,我对其确定泄漏的算法持怀疑态度。它的文档说,“泄漏概率”是基于研究表明在整个应用程序生命周期中均匀分配表明存在泄漏,而那些在开始或结束时聚集的分配则没有。这对我来说没有意义;我参与过很多程序,它们在程序的整个生命周期中始终如一地分配,但它们也会清理。
    • 空间不足。回到 DebugDiag。因此,就其确定泄漏的算法对我来说似乎没有意义的程度而言,我还不相信它。如果有一个工具可以向我显示没有出色引用的内存块,我会更高兴。这似乎是确定泄漏的不变方法。
    • 你可以对任何地址使用!heap -p -a,如果它已经被堆分配,它将检索相应的块。入口是内存块的地址。您可以使用 dt _HEAP_ENTRY 显示标题。 user 是分配返回的地址。如果没有调试标志处于活动状态,它将是 Entry+8。
    • DebugDiag 尝试区分泄漏和缓存。当首先加载数据时,在应用程序启动时会构建一些缓存,这就是为什么默认情况下 DebugDiag 在开始监控之前等待 15 分钟。
    猜你喜欢
    • 2018-10-31
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多