Многие пользователи операционных систем windows рано или поздно сталкиваются с необходимостью выяснить почему же любимая операционка «падает в бсод».
О том что это, как искать причину и как её (в зависимости от ситуации) устранять в интернете написано уже немало, но что делать, если нужно выяснить причину максимально быстро и делать это приходится регулярно как, например, работникам сервисов или завсегдатаям компьютерных форумов?
Упростить задачу могут пресловутые твики контекстного меню, благо делаются они довольно просто.
Это пакеты X64 Debuggers And Tools-x64_en-us.msi или X86 Debuggers And Tools-x86_en-us.msi на выбор в зависимости от разрядности используемой ОС и/или личных предпочтений.
Отдельных ссылок на сайте microsoft вы не найдете, но данные пакеты находятся в составе Windows Driver Kit, его можно скачать без установки выбрав соответствующий режим работы инсталятора, пакеты по завершении скачивания будут лежать в папке Windows Kits10WDKInstallers.
Если кому-то нужно, то я загрузил их отдельно на Я.Диск:
X64 Debuggers And Tools-x64_en-us.msi
X86 Debuggers And Tools-x86_en-us.msi
Я решил не устанавливать дебаггер, а просто распаковать msi:
msiexec /a "D:DesktopX64 Debuggers And Tools-x64_en-us.msi" /qb targetdir="D:DesktopTemp"
Такого «портабельного» варианта более чем достаточно. После, для собственного удобства, переместил нужное содержимое из нескольких вложенных папок в C:PortableDebug, чтобы получилось:
C:PortableDebugwindbg.exe
C:PortableDebugkd.exe
+ все остальное. От этого пути и будем отталкиваться в дальнейшем (плюс я внес его в %PATH% опять же, для удобства).
На этом подготовительные мероприятия можно считать завершенными и переходить к описанию процесса создания твика.
Так как в моей задаче предполагается, что дампов бывает много и часто, то нужно максимально ускорить процесс, при этом сделать его достаточно информативным для беглого анализа.
Разбираемся с ключами и командами дебаггера
В качестве основы для будущего твика возьмем вот такой батник, на который достаточно перетянуть нужный дамп.
Для лучшего восприятия информации, в моём понимании, я инвертировал цвета консоли и задал размер окна консоли побольше.
@echo off
title text %1
mode con: cols=170
color F0
title "%1"
kd.exe -nosqm -sup -z "%1" ^
-y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -c ^
"!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q""
pause
exit /b
Тут можно увидеть параметры передаваемые kd.exe, такие как -y, -i и, собственно, -z, которые видели все, кто знает о широко известном в узких кругах kdfe.cmd.
-i !ImagePath! specifies the location of the executables that generated the
fault (see _NT_EXECUTABLE_IMAGE_PATH)
-y !SymbolsPath! specifies the symbol search path (see _NT_SYMBOL_PATH)
-z !CrashDmpFile! specifies the name of a crash dump file to debug
Если брать по аналогии с распространенными инструкциями то тут есть небольшие отличия: в качестве аргументов дополнительно переданы -nosqm и -sup.
-nosqm disables SQM data collection/upload.
-sup enables full public symbol searches
В качестве команд:
!cpuid
!sysinfo cpuinfo
!sysinfo cpuspeed
!sysinfo machineid
Расписывать их не буду, так-как выйдет слишком много копипасты. Кому интересно смогут найти подробнейшую справку debugger.chm в любом из двух *.msi о которых говорилось выше или на docs.microsoft.com -cpuid -sysinfo. Если вкратце — базовая информация о железе пострадавшего.
Вывод скрипта с использованием kd.exe получится практически аналогичен тому, который получился бы при работе непосредственно через windbg, но результат достигается гораздо быстрее так как ничего не нужно открывать, настраивать папки, открывать дамп через меню и вводить команды в дебаггер.
Фильтрация мусорного вывода из консоли
Для первого примера возьмем дамп памяти рандомного юзера. Возникает небольшая проблема с мусором в выводе:
Такое встречается, например, в дампах юзеров использующих активатор odin, что мы и видим в данном примере.
Полный вывод довольно массивный, потому ссылкой на pastebin.
Требуется «отфильтровать» ненужные строки оставив только полезную информацию.
Я использовал findstr, получилось вот такое некрасивое но работающее решение:
findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
Тут findstr использует две регулярки: одна ищет строки начинающиеся с трех звездочек, одного пробела и заканчивающиеся на пробел и три звездочки. Вторая ищет строки начинающиеся с 14-ти звездочек. Ничего более вразумительного средствами findstr я сделать не смог.
(Использовать символы окончания строк в регулярках findstr на выхлопе kd.exe не рекомендую, могут быть проблемы с видом окончания строк выводимого kd.exe. Вместо rn можно получить n, который findstr не считает окончанием строки.Такие себе грабли.)
Весь код предварительного батника с «фильтром» получился такой:
@echo off
title text %1
mode con: cols=170
color F0
title "%1"
kd.exe -nosqm -sup -z "%1" ^
-y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols ^
-c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
pause
exit /b
Полный вывод отфильтрованного варианта также на pastebin.
Результат аналогичный, но без «мусора». 290 строк текста против 894-х. Уже лучше, но еще не всё.
Быстрое создание лога работы дебаггера
Следующий шаг это добавление создания лога, который можно было бы запостить или отправить куда-нибудь.
Для этого нужно передать kd.exe аргумент -loga <«П:уть клогу.log»>
Код принимает следующий вид:
@echo off
title text %1
mode con: cols=170
color F0
title "%1"
set "D=%1"
set L=%D:.dmp=.LOG%
kd.exe -nosqm -sup -loga "%L%" -z "%D%" ^
-y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols ^
-c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
pause
exit /b
Для файла 102516-21949-01.dmp будет сформирован лог 102516-21949-01.LOG в той же папке, что и сам дамп.
В данном случае вывод «мусора» в лог не фильтруется, фильтруется только вывод в консоль, но в моем случае это не принципиально, хотя можно исправить и это очистив лог уже после создания:
@echo off
title text %1
mode con: cols=170
color F0
title "%1"
set "D=%1"
set L=%D:.dmp=.LOG%
kd.exe -nosqm -sup -loga "%L%" -z "%D%" ^
-y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols ^
-c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
set CL=%L:.LOG=_CLEAN.LOG%
type "%L%" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*" >> "%CL%"
del /f /q "%L%"
pause
exit /b
Открытие дампа в windbg
Теперь последний по порядку, но не по значимости шаг: нужна возможность передать дамп непосредственно в windbg.exe и сразу же передать ему команды, которые с большой долей вероятности понадобится вводить. Все делается по аналогии с kd.exe, аргументы и команды принимаемые windbg.exe практически идентичны kd.exe
@echo off
windbg.exe -z "%1" -sup -y ^
"srv*C:Symbols*http://msdl.microsoft.com/download/symbols" -i "srv*C:Symbols*http://msdl.microsoft.com/download/symbols" -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid"
exit /b
В результате дамп откроется сразу в дебаггере и в нем автоматически выполнятся команды перечисленные в ключе -c.
Вывод аналогичный самому первому варианту с той разницей, что дамп открыт сразу в windbg, есть возможность вводить команды для дальнейшего анализа из-за отсутствия в передаваемом списке команд команды q.
(К слову если в предыдущих вариантах скрипта с kd.exe убрать команду q передаваемую в списке команд через аргумент -c, то возможность продолжить работу с дампом появится и там, в том числе с записью лога прямо в процессе.)
Создание твика
Теперь всё это нужно видоизменить, чтобы можно было прикрутить к контекстному меню *.dmp файлов. Собственно, ради чего это и затевалось.
Получились вот такие «однострочники»:
Для варианта с фильтрацией вывода консоли
cmd /d /k mode con: cols=170 & color F0 & title "%1" & kd.exe -nosqm -sup -z "%1" -y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
Для варианта с фильтрацией вывода консоли и с созданием логфайла
(пришлось использовать отложенное расширение переменных)
cmd /d /v /k mode con: cols=170 & color F0 & title "%1" & set "D=%1"& set L=!D:.dmp=.LOG! & kd.exe -nosqm -sup -loga "!L!" -z "!D!" -y srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:Symbols"*http://msdl.microsoft.com/download/symbols -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^*** .* ***" /c:"^**************.*"
Для открытия дампа непосредственно в windbg.exe
"C:PortableDebugwindbg.exe" -z "%1" -sup -y "srv*C:Symbols*http://msdl.microsoft.com/download/symbols" -i "srv*C:Symbols*http://msdl.microsoft.com/download/symbols" -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid"
В реестре создал следующую структуру разделов:
Был создан отдельный тип файла dmp_geek в разделы реестра которого и вносились изменения. Файлы с расширением *.dmp были назначены файлами типа dmp_geek.
В каждом разделе command в строковый параметр по умолчанию были внесены соответствующие однострочники + красивости в виде иконок и удобных имен отображаемых имен пунктов в контекстном меню.
Получился твик добавляющий возможность массового открытия выделенных в папке дампов как в консоли так и в дебаггере с фильтрацией «мусора» и создания логов для каждого дампа по необходимости. Экономит довольно много времени.
После «причёсывания» реестра экспортировал всё в итоговый REG файл готовый для применения.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT.dmp]
@="dmp_geek"
[HKEY_CLASSES_ROOTdmp_geek]
@="dmp_geek"
"FriendlyTypeName"="Дамп памяти"
[HKEY_CLASSES_ROOTdmp_geekDefaultIcon]
@="imageres.dll,142"
[HKEY_CLASSES_ROOTdmp_geekshell]
[HKEY_CLASSES_ROOTdmp_geekshellkd.exe]
"MUIVerb"="Kd.exe"
"Icon"="C:\Portable\Debug\windbg.exe,6"
[HKEY_CLASSES_ROOTdmp_geekshellkd.execommand]
@="cmd /d /k mode con: cols=170 & color F0 & title "%1" & "C:\Portable\Debug\kd.exe" -nosqm -sup -z "%1" -y srv*"C:\Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:\Symbols"*http://msdl.microsoft.com/download/symbols -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^\*\*\* .* \*\*\*" /c:"^\*\*\*\*\*\*\*\*\*\*\*\*\*\*.*""
[HKEY_CLASSES_ROOTdmp_geekshellkd.exe_-loga]
"MUIVerb"="Kd.exe -loga"
"Icon"="C:\Portable\Debug\windbg.exe,6"
[HKEY_CLASSES_ROOTdmp_geekshellkd.exe_-logacommand]
@="cmd /d /v /k mode con: cols=170 & color F0 & title "%1" & set "D=%1"& set L=!D:.dmp=.LOG! & "C:\Portable\Debug\kd.exe" -nosqm -sup -loga "!L!" -z "!D!" -y srv*"C:\Symbols"*http://msdl.microsoft.com/download/symbols -i srv*"C:\Symbols"*http://msdl.microsoft.com/download/symbols -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid; q" | findstr /r /v /c:"^\*\*\* .* \*\*\*" /c:"^\*\*\*\*\*\*\*\*\*\*\*\*\*\*.*""
[HKEY_CLASSES_ROOTdmp_geekshellOpen]
"MUIVerb"="Windbg"
"Icon"="C:\Portable\Debug\windbg.exe,6"
[HKEY_CLASSES_ROOTdmp_geekshellOpencommand]
@=""C:\Portable\Debug\windbg.exe" -z "%1" -sup -y "srv*C:\Symbols*http://msdl.microsoft.com/download/symbols" -i "srv*C:\Symbols*http://msdl.microsoft.com/download/symbols" -c "!analyze -v; !cpuid; !sysinfo cpuinfo; !sysinfo cpuspeed; !sysinfo machineid""
→ Скачать с Я.Диска GEEK_DMP.reg
На этом всё. Теперь можно быстро, хоть и поверхностно, проанализировать сразу пачку дампов.
Автор: Владимир