代码之家  ›  专栏  ›  技术社区  ›  Ghita

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

  •  3
  • Ghita  · 技术社区  · 10 年前

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

    我看到很多68号的街区。在这些块中(我可以使用 !堆-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显示了该区域周围的以下内容 第7页,共8页 (截断)

    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 回复  |  直到 10 年前
        1
  •  2
  •   Thomas Weller    10 年前

    我假设没有为您的应用程序创建本机映像(使用NGen)。在这种情况下,模块(DLL)只包含永远不会执行的IL代码。因此,从本机的角度来看,不会有任何堆栈指向模块内部。

    相反,IL代码将被JIT编译到内存中的另一个位置,例如在您的情况下为7fe9a5cda8。这是真正的代码执行的地方,所以这是您从本机端看到的。

    要将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