Как извлечь следы стека из мини-дампов?
У меня есть целая куча мини-дампов, которые были записаны во время выполнения приложения через 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, которые вам нравятся, если настройки по умолчанию не достаточно.