Как извлечь следы стека из мини-дампов?

У меня есть целая куча мини-дампов, которые были записаны во время выполнения приложения через MiniDumpWriteDump. Мини-дампы были созданы на машине с версией ОС, отличной от моей машины для разработки.

Сейчас я пытаюсь написать программу для извлечения следов стека из мини-дампов, используя dbghelp.dll. Я иду по MINIDUMP_MODULE_LIST и вызываю SymLoadModule64, но при этом не удается загрузить pdbs (kernel32 и т. Д.) С публичного сервера символов. Если я добавлю "C:\Windows\System32" к пути символов, он найдет dll и загрузит символы, но, конечно, они не совпадают с dll из мини-дампов, поэтому результаты бесполезны.

Так как же мне сказать dbghelp.dll скачать и использовать правильные pdbs?

[редактировать]

Я забыл заявить, что SymLoadModule64 принимает только имя файла, а не информацию о версии / контрольной сумме, поэтому очевидно, что только с помощью SymLoadModule64 невозможно dbghelp выяснить, какой pdb следует загрузить.

Эта информация фактически доступна в MINIDUMP_MODULE_LIST, но я не знаю, как передать ее обратно в API dbghelp.

Существует SymLoadModuleEx, который принимает дополнительные параметры, но я понятия не имею, если это то, что мне нужно, или что я должен передать для дополнительных параметров.

[редактировать]

Пока что не повезло, хотя я заметил, что в отладочном SDK также есть dbgeng.dll, распространяемый вместе с dbghelp.dll. MSDN выглядит довольно хорошо задокументировано и говорит, что это тот же самый движок, который использует windbg. Может быть, я могу использовать это для извлечения следов стека.

Если кто-то может указать мне на введение в использование dbgeng.dll для обработки мини-дампов, что, вероятно, также поможет, поскольку MSDN документирует только отдельные компоненты, но не то, как они работают вместе.

2 ответа

Решение

На тот случай, если кто-то захочет автоматизировать извлечение следов стека из дампов, вот что я в итоге сделал:

Как я упоминал в обновлении, можно использовать dbgeng.dll вместо dbghelp.dll, который, похоже, использует тот же движок, что и WinDbg. После некоторых проб и ошибок вот как можно получить хорошую трассировку стека с тем же механизмом загрузки символов, что и в WinDbg.

  • вызовите DebugCreate, чтобы получить экземпляр механизма отладки
  • запрос для IDebugClient4, IDebugControl4, IDebugSymbols3
  • используйте IDebugSymbols3.SetSymbolOptions, чтобы настроить способ загрузки символов (параметры MSD Wingbg указаны в MSDN)
  • используйте IDebugSymbols3.SetSymbolPath, чтобы установить путь к символу, как в WinDbg
  • используйте IDebugClient4.OpenDumpFileWide, чтобы открыть дамп
  • используйте IDebugControl4.WaitForEvent, чтобы дождаться загрузки дампа
  • используйте IDebugSymbols3.SetScopeFromStoredEvent, чтобы выбрать исключение, сохраненное в дампе
  • используйте IDebugControl4.GetStackTrace для получения последних нескольких стековых кадров
  • используйте IDebugClient4.SetOutputCallbacks для регистрации прослушивателя, получающего декодированную трассировку стека
  • используйте IDebugControl4.OutputStackTrace для обработки кадров стека
  • используйте IDebugClient4.SetOutputCallbacks для отмены регистрации обратного вызова
  • освободить интерфейсы

Вызов WaitForEvent представляется важным, поскольку без него следующие вызовы не могут извлечь трассировку стека.

Кроме того, кажется, что там все еще есть утечка памяти, я не могу сказать, что это я не очищаюсь должным образом или что-то внутреннее в dbgeng.dll, но я могу просто перезапускать процесс каждые 20 дампов или около того, поэтому я не исследовал Больше.

Простой способ автоматизировать анализ нескольких файлов мини-дампов - использовать сценарии, написанные Джоном Роббинсом в его статье "Автоматизация анализа множества файлов мини-дампов с помощью WinDBG и PowerShell" (вы можете получить код на GitHub).

Его легко настроить, чтобы он выполнял любые команды WinDbg, которые вам нравятся, если настройки по умолчанию не достаточно.

Другие вопросы по тегам