Я хотел бы получить трассировку стека потока, который вызывает сбой, вызывая предопределенные команды, написанные в сценарии, чтобы я запускал сценарий и получал файл журнала, содержащий обратную трассировку всех потоков. Затем я могу проанализировать этот файл журнала, чтобы увидеть, есть ли известная проблема.
печать трассировки стека для дампа ядра Windows без необходимости интерактивного входа в Windbg/Visual Studio
Ответы (3)
Я рекомендую вам взглянуть на cdb
. Это довольно полнофункциональная версия командной строки для командной строки, и она уже должна быть установлена вместе с windbg.
Вы можете указать ему открыть дамп, распечатать трассировку стека и выйти из командной строки:
cdb -z yourdump.dmp -c "~*kv; q"
Или вы могли бы даже проявить фантазию и провести автоматический анализ с помощью:
cdb -z yourdump.dmp -c "!analyze -v; q"
Это, вероятно, имеет больше смысла, так как он попытается восстановить стек в то время, когда возникло исключение второго шанса, где простая печать стеков с k
полностью упустила бы проблему. Вы также можете использовать FAILURE_BUCKET_ID
, которые он выводит, чтобы сделать большую часть категоризации за вас.
Оттуда это просто вопрос использования перед командой, которую вы хотите выполнить .logopen
или перенаправление вывода командной строки в файл.
Вы можете запустить WinDbg или Cdb с параметром -z
для открытия дампа, -c
для выполнения команд, -log
для вывода вывода в файл и -y
для настройки пути к символу.
Чтобы запустить скрипт из файла, попробуйте одну из $<
, $><
, $$<
, $$><
или $$>a<
для команды. Прочитайте файл справки WinDbg о различиях между ними.
Обычно не имеет значения, но для полноты: обратите внимание, что некоторые команды не поддерживаются сценариями (MSDN).
Если дамп является полным дампом памяти ядра (мини-дампы размером 64 КБ по умолчанию (размер xp-sp3) не содержат достаточной информации о стеках потоков)
это если вы установили в mycomputers -> свойства-> дополнительно -> запуск и восстановление -> полный дамп памяти)
проверяемый с
F:\>reg query hklm\system\currentcontrolset\control\crashcontrol /v DumpFile
! REG.EXE VERSION 3.0
HKEY_LOCAL_MACHINE\system\currentcontrolset\control\crashcontrol
DumpFile REG_EXPAND_SZ %SystemRoot%\MEMORY.DMP
F:>
вы можете использовать !for_each_thread @#Thread для вывода трассировки стека всех потоков
приведенный ниже пример взят из виртуальной машины xp-sp3, настроенной для записи полного дампа памяти на синем экране, подключенном к kd на хосте.
я выпускаю .crash и крашу виртуальную машину
kd> .crash
Shutdown occurred at (Tue Jul 8 11:10:51.421 2014 (UTC + 5:30))...unloading all symbol tables.
Waiting to reconnect...
при перезагрузке цель пишет MEMORY.DMP, который я копирую в общую папку хоста (может делать и в цели, но на этой виртуальной машине не установлен WindBG, поэтому скопирован на хост)
и я запускаю эту команду
F:\>cdb -c ".logopen c:\\foost.txt;!for_each_thread !thread @#Thread 16; .logclo
se;q" -z c:\sharedwithvm\MEMORY.DMP
это открывает каждый поток в дампе, устанавливает правильный контекст процесса и выгружает информацию о стеке в файл и завершает работу (может занять несколько минут/часов в зависимости от размера дампа)
на виртуальной машине было запущено 302 потока, когда она была аварийно завершена. трассировки стека для всех 302 потоков, хранящихся в c:\foost.txt.
C:\>cdb -c ".shell -ci \"!for_each_thread .echo @#Thread ;q\" wc -l" -z c:\share
dwithvm\MEMORY.DMP | grep -A 1 Reading
kd> cdb: Reading initial command '.shell -ci "!for_each_thread .echo @#Thread ;q
" wc -l'
303 <---------------
C:\>grep ChildEBP foost.txt | wc -l
302 <---------------------
C:\>