Вы не можете получить надежный стек вызовов из потока, который в данный момент выполняется.Чтобы получить стек вызовов из файла дампа, WinDbg извлекает контекстную запись потока из файла дампа (структура CONTEXT, которая в основном является снимком всех регистров для потока).На основе регистров (в частности, RIP и RSP) и символов он может проходить по стеку и извлекать стек вызовов.Для запущенного потока нет способа получить согласованную структуру CONTEXT, потому что она меняет каждую инструкцию.
Ссылка, на которую вы смотрели в MSDN, упоминала простой способ получить согласованный КОНТЕКСТ для текущего выполняющегося потока.Код выглядит следующим образом:
__try
{
RaiseException(0, 0, 0, 0);
}
__except (
MyStackTraceFilter(GetExceptionInformation()->ContextRecord)))
{
// do nothing in the handler
}
Здесь работа выполняется в MyStackTraceFilter - вы должны предоставить эту функцию.Входным параметром будет запись CONTEXT, на которую вы можете положиться - снимок текущего потока в определенное время, когда возбуждается исключение.Вы действительно можете написать код для обхода стека внутри MyStackTraceFilter, и вы получите хороший стек вызовов запущенного потока.Это может оказаться обходным решением, если вы заинтересованы только в стеке вызовов.
В большинстве случаев возможно получить «лучший» стек вызовов из несовместимой структуры CONTEXT.Если вы можете полагать, что RSP / esp более или менее корректен, то вы делаете
- сбросить стек («dds esp» для x86 или «dqs rsp» для x64)
- попытайтесь угадать, где был последний кадр стека перед исключением
- используйте команду 'k BasePtr StackPtr InstructionPtr', чтобы выгрузить стек вызовов