I'm working with heap_stat, a script, based on PYKD library (the script performs Ptrptr()
on !heap -h 0
results and continues from there).
This heap_stat script sometimes contains wrong results, as you can see from following excerpt:
heap_stat source code:
if (type_name.endswith("CStringArray") or
... :
if type_name.endswith("CStringArray"):
collection_Size = typedVar('CStringArray', ptr).m_nSize
elif
...
try:
dprintln(("0x" + pointer_format + "\t%s\t Size:[%d]") % (ptr, type_name, collection_Size))
Results excerpts:
...
0x000002660b40d890 mfc140u!CStringArray Size:[9],
...
0x000002660ae8c6d0 mfc140u!CStringArray Size:[8589934592]
...
Verifying this in Visual Studio yields following results:
- (CStringArray*)0x000002660b40d890 0x000002660b40d890 {size = 9, pointer : 0x000002660b40d890}
[size] 9 __int64
[capacity] 9 __int64
[grow by] 0 __int64
+ [0] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [1] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [2] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [3] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [4] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [5] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [6] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [7] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
+ [8] L"" mfc140u.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >
=> Correct
- (CStringArray*)0x000002660ae8c6d0 0x000002660ae8c6d0 {size = 8589934592, pointer : 0x000002660ae8c6d0}
[size] 8589934592 __int64
[capacity] 8589934594 __int64
[grow by] 8589934594 __int64
+ [Raw View] 0x000002660ae8c6d0 {m_pData=0x88000000bb1d05ba ??? m_nSize=8589934592 m_nMaxSize=8589934594 ...}
=> Wrong: this seems to be a leftover of an object which is not valid anymore.
My question: is there any feature in PYKD to filter out those wrong objects? Is there even a way to recognise those while debugging in Visual Studio? And not to forget: what are those leftovers? I don't think there's much delete array_with_strings
where array_with_strings
is a CStringArray in my source code.
In response to IInspectable's comment: that was a real coincidence, having exactly that number. But it put me thinking: are there any limitations to that number, and in fact, it's very simple:
The size of a CStringArray
(or any other MFC
collection for that matter) is an int
, which means that it is bounded by INT_MAX
(being 2^21-1
).
So, I've adapted my heap_stat script, filtering out all MFC
objects, having a size, larger than 2^21-1
.