windbg: получение трассировки стека для минидампа, созданного в UnhandledExceptionFilter - PullRequest
0 голосов
/ 31 марта 2011

Я устанавливаю фильтр необработанных исключений, выполняя: SetUnhandledExceptionFilter (UnhandledException)

и в своей функции UnhandledException я записываю мини-дамп с использованием MiniDumpWriteDump:

MiniDumpWriteDump (GetCurrentProcess (),GetCurrentProcessId (), hFile, MiniDumpNormal, excpInfo? & EInfo: NULL, NULL, NULL);

Когда я смотрю на трассировку стека в WinDbg, я не вижу много:

0:023> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
15e7e7dc 08f00150 08f00a78 08f00000 08f00150 ntdll!ZwGetContextThread+0x12
15e7e7fc 777d301e 6f00016e 00000044 627e056a 0x8f00150
15e7e890 777d2ffa 777d2bf2 00000000 00650000 ntdll!RtlInterlockedFlushSList+0x889
15e7e894 777d2bf2 00000000 00650000 077e1b88 ntdll!RtlInterlockedFlushSList+0x865
15e7e8b4 772b14d1 08f00000 00000000 077e0c48 ntdll!RtlInterlockedFlushSList+0x45d
15e7e8d0 777ce023 077e1b88 08f00138 00000001 kernel32!HeapFree+0x14
15e7e8e8 777d48c6 777bfafa 777d419a ffffffff ntdll!RtlFreeHeap+0x7e
15e7e914 777e9ed7 ffffffff 15e7e938 15e7e944 ntdll!RtlImageNtHeader+0xe2
15e7e93c 777e9e49 00010000 00000000 08c70000 ntdll!RtlDestroyHeap+0x139
15e7e958 75d5458e 08f00000 00000000 08ccfe46 ntdll!RtlDestroyHeap+0xab
15e7e9c4 777ce023 104d9250 104d91f0 104d9250 KERNELBASE!HeapDestroy+0xe
00000000 00000000 00000000 00000000 00000000 ntdll!RtlFreeHeap+0x7e

В документации MiniDumpWriteDump упоминается, что трассировка трещин может быть плохой, но я не совсем понимаю, что мне с этим делать: http://msdn.microsoft.com/en-us/library/ms680360%28v=vs.85%29.aspx

Любая помощь приветствуется!

Ответы [ 2 ]

2 голосов
/ 31 марта 2011

Вы не можете получить надежный стек вызовов из потока, который в данный момент выполняется.Чтобы получить стек вызовов из файла дампа, 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', чтобы выгрузить стек вызовов
1 голос
/ 25 сентября 2012

Если вы вызываете MinidumpWriteDump из фильтра необработанных исключений, у вас должен быть допустимый EXCEPTION_POINTERS для передачи параметра MINIDUMP_EXCEPTION_INFORMATION. Если вы сделали это, тогда мини-дамп будет содержать поток исключений, который содержит специальный CONTEXT, который представляет состояние потока сбоя. Когда вы загружаете дамп как это в WinDBG, он отобразит сообщение: В этом файле дампа хранится исключение, представляющее интерес. Доступ к хранимой информации об исключениях можно получить через .ecxr.

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

...