Проблема
Довольно часто во время отладки или анализа креш-дампов требуется узнать содержимое контейнера 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
Комментариев нет:
Отправить комментарий