在本机端相当于!dumpheap -stat

时间:2014-09-09 19:06:28

标签: c++ windbg crash-dumps

我想检查进程的本机堆,以查看内存中存在的本机类以及它们的大小。它相当于sos!dumpheap -stat命令。是否可以在原生方面进行?

2 个答案:

答案 0 :(得分:5)

简短的回答是否定的。您可以查看堆并查看已分配块的 sizes ,但本机代码生命的基本事实之一是您不能依赖它将类型标记放入已分配的对象,因此堆上的对象通常不包含足够的信息来确定其类型。

当您处理类似Windows GDI堆(将类型标记放入已分配的对象)之类的内容时,您可以执行此操作,但对于仅分配和使用内存的其他代码,您需要的信息就是“存在。

我应该补充一点:如果您有调试信息(并且很少关注执行速度),则可能会跟踪分配及其分配的类型,因此您可以从已分配的块中继续工作。内存到实际的对象类型。一些堆调试工具已经完成了至少与此类似的事情,尽管我并不知道你所要求的任何东西。

答案 1 :(得分:3)

我猜你想要检查本机堆的原因是分析堆使用情况,并可能弄清楚堆上的分配的性质以及代码的哪一部分负责。如果是这样,umdh工具的输出是我能想到的最接近的。它比!dumpheap -stat更冗长,但你可以从中获得更多 - 例如您可以通过查看分配调用堆栈来查明负责分配的确切代码。

通常,Umdh用于内存泄漏诊断。要获得进程中所有分配的细分,您需要使用所谓的单转储模式。

虽然Umdh的输出不会直接告诉您什么是分配的本机类型,但在大多数情况下,您可以从分配调用堆栈轻松地派生它。例如,在来自Umdh输出的这个片段中,有0x4a分配消耗总共0x194b0字节,并且分配类型很容易弄清楚,因为std::vector<unsinged short>在调用堆栈中,并且分配是在方法RecordData内完成的: :反序列化

+   194b0 ( 194b0 -     0)     4a allocs    BackTraceD0F18F8
+      4a (    4a -     0)  BackTraceD0F18F8    allocations

ntdll!RtlAllocateHeap+36991
MSVCR120D!_heap_alloc_base+51 (f:\dd\vctools\crt\crtw32\heap\malloc.c, 58)
MSVCR120D!_heap_alloc_dbg_impl+1FF (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 431)
MSVCR120D!_nh_malloc_dbg_impl+1D (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 239)
MSVCR120D!_nh_malloc_dbg+2A (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 302)
MSVCR120D!malloc+19 (f:\dd\vctools\crt\crtw32\misc\dbgmalloc.c, 56)
MSVCR120D!operator new+F (f:\dd\vctools\crt\crtw32\heap\new.cpp, 59)
STestViewer!std::_Allocate<unsigned short>+2F (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 28)
STestViewer!std::allocator<unsigned short>::allocate+19 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 578)
STestViewer!std::_Wrap_alloc<std::allocator<unsigned short> >::allocate+1A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 848)
STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reallocate+57 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1588)
STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reserve+5A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1619)
TestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::resize+FC (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1136)
TestViewer!RecordData::Deserialize+52 (c:\src\stcommonlib\stdmodel.cpp, 174)
TestViewer!SensorDrModel::LoadFromFile+21E (c:\src\stcommonlib\stsmodel.cpp, 50)

在其他情况下,对象的类型在调用堆栈中并不明显,但由于您具有调用ntdll!RtlAllocateHeap+36991 MSVCR120D!_heap_alloc_base+51 (f:\dd\vctools\crt\crtw32\heap\malloc.c, 58) MSVCR120D!_heap_alloc_dbg_impl+1FF (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 431) MSVCR120D!_nh_malloc_dbg_impl+1D (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 239) MSVCR120D!_nh_malloc_dbg+2A (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 302) MSVCR120D!malloc+19 (f:\dd\vctools\crt\crtw32\misc\dbgmalloc.c, 56) MSVCR120D!operator new+F (f:\dd\vctools\crt\crtw32\heap\new.cpp, 59) STestViewer!std::_Allocate<unsigned short>+2F (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 28) STestViewer!std::allocator<unsigned short>::allocate+19 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 578) STestViewer!std::_Wrap_alloc<std::allocator<unsigned short> >::allocate+1A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 848) STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reallocate+57 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1588) STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reserve+5A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1619) TestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::resize+FC (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1136) TestViewer!RecordData::Deserialize+52 (c:\src\stcommonlib\stdmodel.cpp, 174) TestViewer!SensorDrModel::LoadFromFile+21E (c:\src\stcommonlib\stsmodel.cpp, 50) 的源文件名和行号,您可以通过查看源代码来确定它。

总结你用Umdh得到的东西:

  1. 这是直接模拟!dumpheap。
  2. 你会花更多的时间在这上面,因为它非常冗长。
  3. 但是,您可以首先提取有关分配发生的原因的信息,这是您无法做到的!dumpheap。