Проблема
Довольно часто во время отладки или анализа креш-дампов требуется узнать содержимое контейнера map. Насколько мне известно, WinDbg для этого не предоставляет никаких средств.
Решение
Решить задачу можно несколькими способами:
Мною был выбран последний способ, поскольку, он имеет следующие преимущества:
Буквально за вечер был создан скрипт позволяющий распечатывать содержимое контейнера. Его последнюю версию можно взять в репозитории проекта или же установив новейшую версию расширения pykd с помощью инсталлятора.
Использование
В качестве примера рассмотрим определённый следующим образом контейнер:
В данный момент скрипт поддерживает реализацию контейнера map из библиотеки STLPort. Корректно работает на платформах x86 и x64.
Пожелания, предложения, ошибки или недочёты можно оставлять в комментариях или создать соответствующий Work Item на странице проекта pykd.
Рабочая среда: WinDbg 6.12.0002.633, pykd 0.0.0.16, STLPort 5.2
Довольно часто во время отладки или анализа креш-дампов требуется узнать содержимое контейнера map. Насколько мне известно, WinDbg для этого не предоставляет никаких средств.
Решение
Решить задачу можно несколькими способами:
- Зная внутреннюю структуру контейнера вручную найти необходимые смещения структур в памяти;
- Создать своё расширение отладчика;
- Воспользоваться возможностями расширения pykd.
Мною был выбран последний способ, поскольку, он имеет следующие преимущества:
- Относительно низкий порог вхождения. Для создания скриптов вполне достаточно ознакомиться с синтаксисом языка Python, pykd API и примерами;
- Высокая скорость разработки;
- Несравнимо удобный синтаксис языка Python по сравнению с синтаксисом скриптового движка WinDbg;
- Возможность отладки скриптов.
Буквально за вечер был создан скрипт позволяющий распечатывать содержимое контейнера. Его последнюю версию можно взять в репозитории проекта или же установив новейшую версию расширения pykd с помощью инсталлятора.
Использование
В качестве примера рассмотрим определённый следующим образом контейнер:
struct CSome
{
int Field1;
char Field2;
};
typedef std::map<int, CSome*> CSomeMap;
CSomeMap someMapName;
Распечатать содержимое структуры CSome можно так:0:000:x86> .foreach ( x {!py stlp map someMapName}) { .block {.echo "------------------------------"}; dt CSome poi(${x} + 0x4) }
------------------------------
StlportMapTest!CSome
+0x000 Field1 : 0n100
+0x004 Field2 : 65 'A'
------------------------------
StlportMapTest!CSome
+0x000 Field1 : 0n200
+0x004 Field2 : 66 'B'
------------------------------
StlportMapTest!CSome
+0x000 Field1 : 0n300
+0x004 Field2 : 67 'C'
Следующим образом можно вывести ключ и значение:0:000:x86> .foreach ( x {!py stlp map someMapName}) { .block {.echo "------------------------------"}; dt -r StlportMapTest!stlp_std::pair<int const ,CSome *> x }
------------------------------
+0x000 first : 0n0
+0x004 second : 0x00956d20 CSome
+0x000 Field1 : 0n100
+0x004 Field2 : 65 'A'
------------------------------
+0x000 first : 0n1
+0x004 second : 0x00956dc0 CSome
+0x000 Field1 : 0n200
+0x004 Field2 : 66 'B'
------------------------------
+0x000 first : 0n2
+0x004 second : 0x00956e60 CSome
+0x000 Field1 : 0n300
+0x004 Field2 : 67 'C'
А так же, можно вывести ключ и значение с помощью самого скрипта указав в качестве параметра соответствующий тип:0:000:x86> !py stlp map someMapName "StlportMapTest!stlp_std::pair<int const ,CSome *>"
------------------------------------------------
+0x000 first : 0n0
+0x004 second : 0x00956d20 CSome
+0x000 Field1 : 0n100
+0x004 Field2 : 65 'A'
------------------------------------------------
+0x000 first : 0n1
+0x004 second : 0x00956dc0 CSome
+0x000 Field1 : 0n200
+0x004 Field2 : 66 'B'
------------------------------------------------
+0x000 first : 0n2
+0x004 second : 0x00956e60 CSome
+0x000 Field1 : 0n300
+0x004 Field2 : 67 'C'
При печати полного содержимого карты следует обратить внимание на точное соответствие типа, вплоть до каждого отступа. Для этого можно воспользоваться командой dt:0:000:x86> dt StlportMapTest!stlp_std::pair<*
StlportMapTest!stlp_std::pair<int const ,int>
.......
нужный -> StlportMapTest!stlp_std::pair<int const ,CSome *>
.......
В данный момент скрипт поддерживает реализацию контейнера map из библиотеки STLPort. Корректно работает на платформах x86 и x64.
Пожелания, предложения, ошибки или недочёты можно оставлять в комментариях или создать соответствующий Work Item на странице проекта pykd.
Рабочая среда: WinDbg 6.12.0002.633, pykd 0.0.0.16, STLPort 5.2
Комментариев нет:
Отправить комментарий