我正在阅读这篇文章detecting memory leak using windbg。我正在尝试找到一种方法来打印所有userptack的用户插件,这些用户在针对特定大小的内存块进行过滤时会出现。这可能吗 ? 我希望实现类似的目标:
foreach(userPtr)
dump_to_a_file !heap -p -a userPtr
其中userPtr是:UserPtr,如
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
003360e0 03f0 0000 [07] 003360e8 01f64 - (busy)
00338060 03f0 03f0 [07] 00338068 01f64 - (busy)
00339fe0 03f0 03f0 [07] 00339fe8 01f64 - (busy)
我正在尝试这样做,以避免手动检查数以千计的此类UserPtr。感谢您提供的任何帮助。
答案 0 :(得分:4)
这是!heap -flt s xxx
命令的输出,其中包含堆条目表之前和之后的大量文本。让我们通过做黑客
.shell -ci "!heap -flt s xxx" find "["
现在它的输出非常稳定,可用于foreach循环:
.foreach (userptr {.shell -ci "!heap -flt s xxx" find "["}) { .echo ${userptr}}
了解它如何分割每一行。让我们使用/pS 4 /ps 7
摆脱前4个令牌(条目,大小,上一个,标志)和最后三个令牌(用户名, - ,状态)。
.foreach /pS 4 /ps 7 (userptr {.shell -ci "!heap -flt s xxx" find "["}) { .echo ${userptr}}
现在您已拥有纯地址,请使用!heap -p -a
.foreach /pS 4 /ps 7 (userptr {.shell -ci "!heap -flt s xxx" find "["}) { !heap -p -a ${userptr}}
要将其转储到文件中,请用日志(.logopen
和.logclose
)将其包围:
.logopen d:\debug\logs\heap.log; .foreach /pS 4 /ps 7 (userptr {.shell -ci "!heap -flt s xxx" find "["}) { !heap -p -a ${userptr}}; .logclose
你去。
答案 1 :(得分:1)
您可以使用umdh.exe
。 Umdh可以转储所有分配,或者同一进程的两个快照之间的增量,这是查找内存泄漏的最方便的方法。您可以在安装Windows调试工具的位置找到该工具。
使用您需要知道的umdh.exe时的问题是,它仅在执行增量操作时解析符号,即比较进程的两个快照。如果你真的需要每个callstack,只需在流程执行的最初阶段制作一个快照。
Umdh.exe还将具有相同callstack的分配聚合到桶中,因此在diff输出中,您将看到如下内容:
+ 18f0 ( 2354 - a64) 11 allocs BackTrace113457DC
+ c ( 11 - 5) BackTrace113457DC allocations
ntdll!RtlAllocateHeap+38CB9
msvcrt!_calloc_impl+134
msvcrt!_calloc_crt+16
msvcrt!_CRTDLL_INIT+FC
ntdll!LdrxCallInitRoutine+16
ntdll!LdrpCallInitRoutine+43
ntdll!LdrpInitializeThread+106
ntdll!_LdrpInitialize+6A
ntdll!LdrInitializeThunk+10
这是11个分配的调用堆栈示例,此调用堆栈的分配数量在快照之间从5增加到11,这些分配从0xa64到0x2354字节消耗的内存。
显示如何使用umdh.exe的示例步骤:
set _NT_SYMBOL_PATH=%CD%;srv*http://msdl.microsoft.com/download/symbols
umdh -p: -f:MyFirstSnapshot.txt
umdh -p: -f:MySecondSnapshot.txt
umdh MyFirstSnapshot.txt MySecondSnapshot.txt -f:MyDiff.txt