[Open source, C++, Отладка, Разработка под Windows] Полезные скрипты для WinDBG: команда !exccandidates
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Некоторое время назад мы опубликовали в OpenSource небольшую библиотечку скриптов для популярного отладчика Windbg. Они предназначены для автоматизации ряда рутинных задач, возникающих при анализе причин падения программ как при отладке вживую, так и при работе с дампами памяти. Мы запланировали несколько постов, объясняющих, как эти скрипты использовать. Вот первый пост из данного цикла. Он демонстрирует использование команды !exccandidates на синтетическом примере.Иногда при разборе дампа возникает подозрение, что случившееся исключение тут уже не первое, но при этом прямых ссылок на него нигде не сохранилось. Таких ситуаций не так уж и мало: например, повторные исключения могут возникнуть в процессе обработки исключения или при раскрутке стека после исключения; они могут быть спровоцированы состоянием переменных после первого исключения; наконец, такое часто происходит при использовании сторонних библиотек, которые применяют другую модель обработки ошибок. Во всех этих случаях можно попытаться найти на стеке записи от предыдущих исключений. Гарантии, что они остались в целости и сохранности, конечно, нет, но во многих случаях это удается.Сам по себе трюк с поиском исключений достаточно широко известен — нужно поискать какие-то редко меняющиеся части структуры CONTEXT. Обычно ищут флаги (хотя они-то как раз могут быть изменены) или сегментные регистры, что, как мне кажется, надежнее. Команда !exccandidates автоматизирует данный процесс и обрезает лишнее, оставляя только те исключения, которые произошли в выбранном потоке.Для примера возьмем вот такую небольшую программку:
#include <exception>
class A
{
public:
A()
{
throw(std::exception("It's too cold!"));
}
};
class B
{
public:
bool Do()
{
try
{
A a;
return true;
}
catch (const std::exception&)
{
return false;
}
}
};
class Log
{
public:
void Notify(const char* msg)
{
message = msg;
}
private:
const char* message;
};
class C
{
public:
C()
{
B b;
if (!b.Do())
reinterpret_cast<Log*>(1)->Notify("I don't know what happened!"); // Simulating tracer lifetime error
}
};
int main()
{
C c;
return 0;
}
Она имитирует ситуацию, когда после ошибки обнаруживается, что у нас есть проблема с временем жизни трейсера. Естественно, проблему с трейсером надо чинить, но чтобы два раза не обуваться, почему бы не попытаться заодно выяснить, в чем заключалась первичная ошибка.При запуске этой программы под Windbg выполнение останавливается на ожидаемом AV. Для удобства find_exception.cpp можно скачать вот отсюда.Вот стек, который мы видим:
>.ecxr; k
# ChildEBP RetAddr
00 (Inline) -------- find_exception!Log::Notify [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 34]
01 (Inline) -------- find_exception!C::{ctor}+0x9 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 48]
02 006ffbf4 00cd1387 find_exception!main+0x9 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 54]
03 (Inline) -------- find_exception!invoke_main+0x1c [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
04 006ffc3c 7749fa29 find_exception!__scrt_common_main_seh+0xfa [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
05 006ffc4c 778a76b4 kernel32!BaseThreadInitThunk+0x19
06 006ffca8 778a7684 ntdll!__RtlUserThreadStart+0x2f
07 006ffcb8 00000000 ntdll!_RtlUserThreadStart+0x1b
Естественно, никаких указаний на исходное исключение тут нет. Но мы можем их поискать:
>!exccandidates
Searching for exception candidate in current thread
Stack top: 0x600000
Found exception 0
.exr 0x6ff5f0 - exception code 0xe06d7363
.cxr 0x6ff640
@$exccandidates() : 0x1
Отлично, нашлось плюсовое исключение — 0xe06d7363. Посмотрим его, для чего воспользуемся командами, которые нам любезно подсказывает скрипт:
>.exr 0x6ff5f0
ExceptionAddress: 7773a8b2 (KERNELBASE!RaiseException+0x00000062)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3
Parameter[0]: 19930520
Parameter[1]: 006ffbbc
Parameter[2]: 00cd2724
pExceptionObject: 006ffbbc
_s_ThrowInfo : 00cd2724
Type : class std::exception
И стек:
>.cxr 0x6ff640; k
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
00 006ffb7c 711f7a86 KERNELBASE!RaiseException+0x62
01 006ffbac 00cd110d VCRUNTIME140!_CxxThrowException+0x66 [d:\agent\_work\9\s\src\vctools\crt\vcruntime\src\eh\throw.cpp @ 74]
02 006ffbc8 00cd1145 find_exception!A::A+0x1d [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 8]
03 006ffbf0 00cd1175 find_exception!B::Do+0x35 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 24]
04 (Inline) -------- find_exception!C::{ctor}+0x5 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 47]
05 006ffbf4 00cd1387 find_exception!main+0x5 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 54]
06 (Inline) -------- find_exception!invoke_main+0x1c [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
07 006ffc3c 7749fa29 find_exception!__scrt_common_main_seh+0xfa [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
08 006ffc4c 778a76b4 kernel32!BaseThreadInitThunk+0x19
09 006ffca8 778a7684 ntdll!__RtlUserThreadStart+0x2f
0a 006ffcb8 00000000 ntdll!_RtlUserThreadStart+0x1b
Вот таким образом иногда удается заглянуть чуть дальше в поисках причин падения.
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, JavaScript, Программирование, TypeScript] 5 фактов о том, как Microsoft приватизировала открытый исходный код, убивая JavaScript в процессе (перевод)
- [Программирование, C++, Распределённые системы, Микросервисы] С чего начать писать микросервис на C++
- [Программирование, Совершенный код, C++, Лайфхаки для гиков] Прочти меня: код, который не выбесит соседа
- [C++] Доступ к элементам std::tuple во время исполнения программы
- [Программирование, C++, Промышленное программирование, Программирование микроконтроллеров] Маленькие хитрости для STM32
- [Open source, Сетевые технологии, Mesh-сети, Разработка систем связи] Yggdrasil Network: Заря бытовых меш-сетей, или Интернет будущего
- [Информационная безопасность] Security Week 11: уязвимости в Exchange, цензура на Github и таймлайн атаки
- [Open source, Python, Параллельное программирование] Визуализируйте многопоточные программы Python с open source инструментом – VizTracer (перевод)
- [Программирование, C++, Алгоритмы] Ленивые операции над множествами в C++
- [Open source, Программирование, Геоинформационные сервисы, Визуализация данных, Научно-популярное] Геология XXI века: от реальности к виртуальности
Теги для поиска: #_open_source, #_c++, #_otladka (Отладка), #_razrabotka_pod_windows (Разработка под Windows), #_razrabotka_pod_windows (разработка под windows), #_windbg, #_otladka (отладка), [url=https://torrents-local.xyz/search.php?nm=%23_blog_kompanii_«laboratorija_kasperskogo»&to=0&allw=0&o=1&s=0&f%5B%5D=820&f%5B%5D=959&f%5B%5D=958&f%5B%5D=872&f%5B%5D=967&f%5B%5D=954&f%5B%5D=885&f%5B%5D=882&f%5B%5D=863&f%5B%5D=881&f%5B%5D=860&f%5B%5D=884&f%5B%5D=865&f%5B%5D=873&f%5B%5D=861&f%5B%5D=864&f%5B%5D=883&f%5B%5D=957&f%5B%5D=859&f%5B%5D=966&f%5B%5D=956&f%5B%5D=955]#_blog_kompanii_«laboratorija_kasperskogo» (
Блог компании «Лаборатория Касперского»
)[/url], #_open_source, #_c++, #_otladka (
Отладка
), #_razrabotka_pod_windows (
Разработка под Windows
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 11:54
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Некоторое время назад мы опубликовали в OpenSource небольшую библиотечку скриптов для популярного отладчика Windbg. Они предназначены для автоматизации ряда рутинных задач, возникающих при анализе причин падения программ как при отладке вживую, так и при работе с дампами памяти. Мы запланировали несколько постов, объясняющих, как эти скрипты использовать. Вот первый пост из данного цикла. Он демонстрирует использование команды !exccandidates на синтетическом примере.Иногда при разборе дампа возникает подозрение, что случившееся исключение тут уже не первое, но при этом прямых ссылок на него нигде не сохранилось. Таких ситуаций не так уж и мало: например, повторные исключения могут возникнуть в процессе обработки исключения или при раскрутке стека после исключения; они могут быть спровоцированы состоянием переменных после первого исключения; наконец, такое часто происходит при использовании сторонних библиотек, которые применяют другую модель обработки ошибок. Во всех этих случаях можно попытаться найти на стеке записи от предыдущих исключений. Гарантии, что они остались в целости и сохранности, конечно, нет, но во многих случаях это удается.Сам по себе трюк с поиском исключений достаточно широко известен — нужно поискать какие-то редко меняющиеся части структуры CONTEXT. Обычно ищут флаги (хотя они-то как раз могут быть изменены) или сегментные регистры, что, как мне кажется, надежнее. Команда !exccandidates автоматизирует данный процесс и обрезает лишнее, оставляя только те исключения, которые произошли в выбранном потоке.Для примера возьмем вот такую небольшую программку: #include <exception>
class A { public: A() { throw(std::exception("It's too cold!")); } }; class B { public: bool Do() { try { A a; return true; } catch (const std::exception&) { return false; } } }; class Log { public: void Notify(const char* msg) { message = msg; } private: const char* message; }; class C { public: C() { B b; if (!b.Do()) reinterpret_cast<Log*>(1)->Notify("I don't know what happened!"); // Simulating tracer lifetime error } }; int main() { C c; return 0; } >.ecxr; k
# ChildEBP RetAddr 00 (Inline) -------- find_exception!Log::Notify [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 34] 01 (Inline) -------- find_exception!C::{ctor}+0x9 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 48] 02 006ffbf4 00cd1387 find_exception!main+0x9 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 54] 03 (Inline) -------- find_exception!invoke_main+0x1c [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 04 006ffc3c 7749fa29 find_exception!__scrt_common_main_seh+0xfa [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 05 006ffc4c 778a76b4 kernel32!BaseThreadInitThunk+0x19 06 006ffca8 778a7684 ntdll!__RtlUserThreadStart+0x2f 07 006ffcb8 00000000 ntdll!_RtlUserThreadStart+0x1b >!exccandidates
Searching for exception candidate in current thread Stack top: 0x600000 Found exception 0 .exr 0x6ff5f0 - exception code 0xe06d7363 .cxr 0x6ff640 @$exccandidates() : 0x1 >.exr 0x6ff5f0
ExceptionAddress: 7773a8b2 (KERNELBASE!RaiseException+0x00000062) ExceptionCode: e06d7363 (C++ EH exception) ExceptionFlags: 00000001 NumberParameters: 3 Parameter[0]: 19930520 Parameter[1]: 006ffbbc Parameter[2]: 00cd2724 pExceptionObject: 006ffbbc _s_ThrowInfo : 00cd2724 Type : class std::exception >.cxr 0x6ff640; k
*** Stack trace for last set context - .thread/.cxr resets it # ChildEBP RetAddr 00 006ffb7c 711f7a86 KERNELBASE!RaiseException+0x62 01 006ffbac 00cd110d VCRUNTIME140!_CxxThrowException+0x66 [d:\agent\_work\9\s\src\vctools\crt\vcruntime\src\eh\throw.cpp @ 74] 02 006ffbc8 00cd1145 find_exception!A::A+0x1d [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 8] 03 006ffbf0 00cd1175 find_exception!B::Do+0x35 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 24] 04 (Inline) -------- find_exception!C::{ctor}+0x5 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 47] 05 006ffbf4 00cd1387 find_exception!main+0x5 [e:\Work\Perforce\core_tech_from_p4\_articles_\WinDbg public scripts\find_exception\find_exception.cpp @ 54] 06 (Inline) -------- find_exception!invoke_main+0x1c [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 07 006ffc3c 7749fa29 find_exception!__scrt_common_main_seh+0xfa [d:\agent\_work\57\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 08 006ffc4c 778a76b4 kernel32!BaseThreadInitThunk+0x19 09 006ffca8 778a7684 ntdll!__RtlUserThreadStart+0x2f 0a 006ffcb8 00000000 ntdll!_RtlUserThreadStart+0x1b =========== Источник: habr.com =========== Похожие новости:
Блог компании «Лаборатория Касперского» )[/url], #_open_source, #_c++, #_otladka ( Отладка ), #_razrabotka_pod_windows ( Разработка под Windows ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 11:54
Часовой пояс: UTC + 5