Windows堆分配调用堆栈 - 奇怪的callstack

时间:2014-09-11 14:21:32

标签: c++ windows debugging memory-leaks windbg

我正在尝试分析托管进程内存转储,如果本机内存泄漏则可疑。为了能够使用windbg(并从那里使用!heap扩展),我为服务器进程激活了用户模式调用堆栈

我看到很多大小为68的块。在那些块(我可以使用!heap -p -a 手动验证的块)中,有许多形式的调用堆栈

 !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 (截断)

start             end                module name
00000000`773b0000 00000000`774cf000   kernel32   (pdb symbols)
00000000`774d0000 00000000`775ca000   user32     (deferred)
00000000`775d0000 00000000`77779000   ntdll      (pdb symbols)
00000000`77790000 00000000`77797000   psapi      (deferred)
00000000`777a0000 00000000`777a3000   normaliz   (deferred)
00000001`3f810000 00000001`3f818000   ManagedService  (deferred)             
000007fe`dd2d0000 000007fe`de398000   System_Web_ni   (deferred)

1 个答案:

答案 0 :(得分:2)

我假设没有为您的应用程序创建本机映像(使用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方法名称(此处示例,因为我没有转储):

MethodDesc: 000007ff00033450
Method Name: ManagedService.Program.Main()
Class: 000007ff00162438
MethodTable: 000007ff00033460
mdToken: 0600001f
Module: 000007ff00032e30
IsJitted: yes
CodeAddr: 000007ff00170120