C++ Windows堆分配调用堆栈-奇怪的调用堆栈
我正在尝试分析托管进程内存转储,如果怀疑本机内存泄漏。为了能够使用windbg(并从那里使用!heap extension),我为服务器进程激活了用户模式调用堆栈 我看到很多68码的街区。在这些块(我可以使用!heap-p-a手动验证的块)中,有许多这种形式的调用堆栈C++ Windows堆分配调用堆栈-奇怪的调用堆栈,c++,windows,debugging,memory-leaks,windbg,C++,Windows,Debugging,Memory Leaks,Windbg,我正在尝试分析托管进程内存转储,如果怀疑本机内存泄漏。为了能够使用windbg(并从那里使用!heap extension),我为服务器进程激活了用户模式调用堆栈 我看到很多68码的街区。在这些块(我可以使用!heap-p-a手动验证的块)中,有许多这种形式的调用堆栈 !heap -p -a 000000003ca5cfd0 address 000000003ca5cfd0 found in _HEAP @ 1ea0000 HEAP_ENTRY Si
!heap -p -a 000000003ca5cfd0
address 000000003ca5cfd0 found in
_HEAP @ 1ea0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
000000003ca5cfa0 0009 0000 [00] 000000003ca5cfd0 00068 - (busy)
7766bbed ntdll! ?? ::FNODOBFM::`string'+0x000000000001913b
7fef7b76a57 msvcr120!malloc+0x000000000000005b
7fef7b76967 msvcr120!operator new+0x000000000000001f
7fe9a5cdaf8 +0x000007fe9a5cdaf8
你知道这些分配是什么吗,因为它们在我的转储文件中占用了数百MB的空间
编辑
lm在区域周围显示以下内容7fe9a5cdaf8(截断)
我假设没有为您的应用程序创建本机映像(使用NGen)。在这种情况下,模块(DLL)只包含永远不会执行的IL代码。因此,从本机的角度来看,不会有任何堆栈指向模块内部 相反,IL代码将被JIT编译到内存中的另一个位置,例如在您的情况下为7fe9a5cdaf8。这是执行真正代码的地方,所以这是您从本机端看到的 要将JIT编译的指令还原为其.NET方法描述符,请执行以下操作:
0:000> .symfix
0:000> .loadby sos mscorwks ; *** .NET 2
0:000> .loadby sos clr ; *** .NET 4
0:000> !ip2md 7fe9a5cdaf8
然后,输出应显示.NET方法名称(此处为示例,因为我没有您的转储):
您缺少任何模块的符号
7fe9a5cdaf8
。运行lm
并查找地址对应的模块,查看是否找不到该模块的符号。@PatrickQuirk在ManagedService和System_Web_ni之间的区域中没有映射的模块。在这种情况下,可能是动态代码。我不确定下一步是什么,除了添加一个来尝试获得更好的堆栈跟踪。@PatrickQuirk这可能是一个有效的点,但在用户转储中有它。我想知道我们如何识别为进程的用户模式调用堆栈分配的内存。堆栈应该是进程转储的一部分,这很粗糙。你有我的一票!谢谢你的建议。最后,需要在一个活动进程上为68字节的分配设置一个断点,奇怪的是,需要使用!ip2md指令。代码是C++ CLI,分配一些本地内存泄漏。我想知道我是否能在其他地方找到更多关于这个ip2md的信息。。。
0:000> .symfix
0:000> .loadby sos mscorwks ; *** .NET 2
0:000> .loadby sos clr ; *** .NET 4
0:000> !ip2md 7fe9a5cdaf8
MethodDesc: 000007ff00033450
Method Name: ManagedService.Program.Main()
Class: 000007ff00162438
MethodTable: 000007ff00033460
mdToken: 0600001f
Module: 000007ff00032e30
IsJitted: yes
CodeAddr: 000007ff00170120