1 Вопрос: как распознать «неправильные» указатели

вопрос создан в Thu, May 2, 2019 12:00 AM

Я работаю со сценарием heap_stat, основанным на библиотеке PYKD (сценарий выполняет Ptrptr() для результатов !heap -h 0 и продолжает оттуда).

Этот сценарий heap_stat иногда содержит неверные результаты, как вы можете видеть из следующей выдержки:

Исходный код heap_stat:

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))

Отрывки результатов:

...
0x000002660b40d890      mfc140u!CStringArray     Size:[9],
...
0x000002660ae8c6d0      mfc140u!CStringArray     Size:[8589934592]
...

Проверка этого в Visual Studio дает следующие результаты:

-    (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> > >

= &GT; Правильно

-    (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 ...}

= &GT; Неправильно: это, кажется, остаток объекта, который больше не действителен.

Мой вопрос: есть ли какая-либо функция в PYKD для фильтрации этих неправильных объектов? Есть ли способ распознать их во время отладки в Visual Studio? И не забывать: что это за остатки? Я не думаю, что есть много delete array_with_strings, где array_with_strings - это CStringArray в моем исходном коде.

    
0
  1. Эти «остатки» выглядят как значения часового. Десятичное значение 8589934592 равно 0x2'0000'0000 в шестнадцатеричном формате, что не похоже на разумное значение размера.
    2019-05-03 08: 32: 44Z
1 ответ                              1                         

В ответ на комментарий IInspectable: это было реальное совпадение, имея именно это число. Но это заставило меня задуматься: есть ли ограничения на это число, и на самом деле все очень просто:

Размер CStringArray (или любой другой коллекции MFC по этому вопросу) равен int, что означает, что он ограничен INT_MAX (будучи 2^21-1).

Итак, я адаптировал свой сценарий heap_stat, отфильтровывая все объекты MFC, размер которых больше 2^21-1.

    
0
2019-05-03 09: 47: 03Z
  1. INT_MAX равно 2^32-1 или 0xFFFF'FFFF. У вас действительно есть столько строк в памяти?
    2019-05-03 13: 00: 26Z
  2. @ BarmakShemirani: в соответствии с " docs.microsoft.com/en-us/cpp/c-language/… ", INT_MAX равно 2 ^ 21-1, а не 2 ^ 32 -1. У меня точно нет такого количества записей в памяти, но у меня не было максимального значения, которое я мог бы проверить.
    2019-05-03 13: 07: 19Z
  3. Хорошо, мы оба не правы. INT_MAX - это 2^31 - 1 или 0x7FFF'FFFF. Кстати, 8589934592 - это 64-разрядное целое число. Я не уверен, как вы в конечном итоге с этим значением. Убедитесь, что индекс >= 0 и меньше m_stringarray.GetCount()
    2019-05-03 13: 41: 15Z
источник размещен Вот