Поделиться через


Использование расширения !analyze

Первым шагом при отладке аварийного целевого компьютера или приложения является использование команды расширения !analyze . Это расширение выполняет большой объем автоматизированного анализа. Результаты этого анализа отображаются в окне команды отладчика.

Для полного подробного отображения данных следует использовать параметр -v . Дополнительные сведения о других параметрах см. на странице справки по !анализу.

Пример пользовательского режима !analyze -v

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

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Debugger SolutionDb Connection::Open failed 80004005

Если вы подключены к Интернету, отладчик пытается получить доступ к базе данных решений аварийного сбоя, поддерживаемых корпорацией Майкрософт. В этом случае отображается сообщение об ошибке, указывающее, что компьютер не мог получить доступ к Интернету или веб-сайту.

FAULTING_IP: 
ntdll!PropertyLengthAsVariant+73
77f97704 cc               int     3

В поле FAULTING_IP показан указатель инструкции во время сбоя.

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 77f97704 (ntdll!PropertyLengthAsVariant+0x00000073)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 3
   Parameter[0]: 00000000
   Parameter[1]: 00010101
   Parameter[2]: ffffffff

В поле EXCEPTION_RECORD показана запись исключения для этого сбоя. Эти сведения также можно просмотреть с помощью команды EXR (Отображаемая запись исключений).

BUGCHECK_STR:  80000003

В поле BUGCHECK_STR показан код исключения. Имя является неправильным— проверка ошибок термина фактически означает сбой режима ядра. В отладке в пользовательском режиме будет отображаться код исключения( в данном случае 0x80000003.

DEFAULT_BUCKET_ID:  APPLICATION_FAULT

В поле DEFAULT_BUCKET_ID показана общая категория сбоев, к которым относится этот сбой.

PROCESS_NAME:  MyApp.exe

Поле PROCESS_NAME указывает имя процесса, вызвавого исключение.

LAST_CONTROL_TRANSFER:  from 01050963 to 77f97704

В поле LAST_CONTROL_TRANSFER отображается последний вызов в стеке. В этом случае код по адресу 0x01050963 вызывает функцию в 0x77F97704. Эти адреса можно использовать с командой ln (Список ближайших символов), чтобы определить, в каких модулях и функциях находятся эти адреса.

STACK_TEXT:  
0006b9dc 01050963 00000000 0006ba04 000603fd ntdll!PropertyLengthAsVariant+0x73
0006b9f0 010509af 00000002 0006ba04 77e1a449 MyApp!FatalErrorBox+0x55 [D:\source_files\MyApp\util.c @ 541]
0006da04 01029f4e 01069850 0000034f 01069828 MyApp!ShowAssert+0x47 [D:\source_files\MyApp\util.c @ 579]
0006db6c 010590c3 000e01ea 0006fee4 0006feec MyApp!SelectColor+0x103 [D:\source_files\MyApp\colors.c @ 849]
0006fe04 77e11d0a 000e01ea 00000111 0000413c MyApp!MainWndProc+0x1322 [D:\source_files\MyApp\MyApp.c @ 1031]
0006fe24 77e11bc8 01057da1 000e01ea 00000111 USER32!UserCallWinProc+0x18
0006feb0 77e172b4 0006fee4 00000001 010518bf USER32!DispatchMessageWorker+0x2d0
0006febc 010518bf 0006fee4 00000000 01057c5d USER32!DispatchMessageA+0xb
0006fec8 01057c5d 0006fee4 77f82b95 77f83920 MyApp!ProcessQCQPMessage+0x3b [D:\source_files\MyApp\util.c @ 2212]
0006ff70 01062cbf 00000001 00683ed8 00682b88 MyApp!main+0x1e6 [D:\source_files\MyApp\MyApp.c @ 263]
0006ffc0 77e9ca90 77f82b95 77f83920 7ffdf000 MyApp!mainCRTStartup+0xff [D:\source_files\MyApp\crtexe.c @ 338]
0006fff0 00000000 01062bc0 00000000 000000c8 KERNEL32!BaseProcessStart+0x3d

В поле STACK_TEXT показана трассировка стека компонента сбоя.

FOLLOWUP_IP: 
MyApp!FatalErrorBox+55
01050963 5e               pop     esi

FOLLOWUP_NAME:  dbg

SYMBOL_NAME:  MyApp!FatalErrorBox+55

MODULE_NAME:  MyApp

IMAGE_NAME:  MyApp.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  383490a9

Если анализ !анализирует инструкцию, которая, вероятно, вызвала ошибку, она отображает ее в поле FOLLOWUP_IP. Поля SYMBOL_NAME, MODULE_NAME, IMAGE_NAME и DEBUG_FLR_IMAGE_TIMESTAMP отображают символ, модуль, имя изображения и метку времени изображения, соответствующую этой инструкции.

STACK_COMMAND:  .ecxr ; kb

В поле STACK_COMMAND показана команда, используемая для получения STACK_TEXT. Эту команду можно использовать для повторения отображения трассировки стека или изменения для получения связанных сведений стека.

BUCKET_ID:  80000003_MyApp!FatalErrorBox+55

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

Followup: dbg
---------

Сведения о полях FOLLOWUP_NAME и последующих действиях см. в разделе "Поле "Отслеживание" и "Файл triage.ini".

Существуют различные поля, которые могут появиться:

  • Если элемент управления был передан в недопустимый адрес, поле FAULTING_IP будет содержать этот недопустимый адрес. Вместо поля FOLLOWUP_IP поле FAILED_INSTRUCTION_ADDRESS будет отображать дизассемблированное код из этого адреса, хотя этот дизассембли, вероятно, будет бессмысленным. В этой ситуации поля SYMBOL_NAME, MODULE_NAME, IMAGE_NAME и DEBUG_FLR_IMAGE_TIMESTAMP будут ссылаться на вызывающий объект этой инструкции.

  • Если обработчик заготовит, вы можете увидеть поля SINGLE_BIT_ERROR, TWO_BIT_ERROR или POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Если произошло повреждение памяти, поле CHKIMG_EXTENSION укажет команду расширения !chkimg , которая должна использоваться для изучения.

Пример режима ядра !analyze -v

В этом примере отладчик подключен к компьютеру, который только что произошел сбой.

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pagable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.

Первый элемент отображения показывает код проверки ошибок и сведения об этом типе проверки ошибок. Некоторые отображаемые тексты могут не применяться к этому конкретному экземпляру. Дополнительные сведения о каждой проверке ошибок см. в разделе "Справочник по коду для проверки ошибок".

Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: f832035c, address which referenced memory

Далее отображаются параметры проверки ошибок. За ними следует описание. Например, третий параметр равен 1, а комментарий, приведенный ниже, объясняет, что это означает, что операция записи завершилась ошибкой.

## Debugging Details:


WRITE_ADDRESS:  00000004 Nonpaged pool

CURRENT_IRQL:  2

Следующие несколько полей зависят от характера аварии. В этом случае мы видим поля WRITE_ADDRESS и CURRENT_IRQL. Это просто перебор сведений, отображаемых в параметрах проверки ошибок. Сравнивая инструкцию "Непагованный пул" с текстом проверки ошибок, который считывает "попытка получить доступ к адресу с разбивкой на страницы (или полностью недопустимый), мы видим, что адрес недопустим. Недопустимый адрес в данном случае был 0x00000004.

FAULTING_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

В поле FAULTING_IP показан указатель инструкции во время сбоя.

DEFAULT_BUCKET_ID:  DRIVER_FAULT

В поле DEFAULT_BUCKET_ID показана общая категория сбоев, к которым относится этот сбой.

BUGCHECK_STR:  0xD1

В поле BUGCHECK_STR показан код проверки ошибок, который мы уже видели. В некоторых случаях добавляется дополнительная информация о триге.

TRAP_FRAME:  f8950dfc -- (.trap fffffffff8950dfc)
.trap fffffffff8950dfc
ErrCode = 00000002
eax=81cc86dc ebx=81cc80e0 ecx=81e55688 edx=00000000 esi=81cc8028 edi=8052cf3c
eip=f832035c esp=f8950e70 ebp=f8950e90 iopl=0         nv up ei pl nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010216
USBPORT!USBPORT_BadRequestFlush+7c:
f832035c 894204           mov     [edx+0x4],eax     ds:0023:00000004=????????
.trap
Resetting default context

В поле TRAP_FRAME показан кадр ловушки для этого сбоя. Эти сведения также можно просмотреть с помощью команды .trap (Display Trap Frame).

LAST_CONTROL_TRANSFER:  from f83206e0 to f832035c

В поле LAST_CONTROL_TRANSFER отображается последний вызов в стеке. В этом случае код по адресу 0xF83206E0 вызывает функцию в 0xF832035C. Чтобы определить, в каком модуле и функции эти адреса находятся, можно использовать команду ln (Список ближайших символов).

STACK_TEXT:  
f8950e90 f83206e0 024c7262 00000000 f8950edc USBPORT!USBPORT_BadRequestFlush+0x7c
f8950eb0 804f5561 81cc8644 81cc8028 6d9a2f30 USBPORT!USBPORT_DM_TimerDpc+0x10c
f8950fb4 804f5644 6e4be98e 00000000 ffdff000 nt!KiTimerListExpire+0xf3
f8950fe0 8052c47c 8053cf20 00000000 00002e42 nt!KiTimerExpiration+0xb0
f8950ff4 8052c16a efdefd44 00000000 00000000 nt!KiRetireDpcList+0x31

В поле STACK_TEXT показана трассировка стека компонента сбоя.

FOLLOWUP_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

Поле FOLLOWUP_IP отображает дизассембли инструкции, которая, вероятно, вызвала ошибку.

FOLLOWUP_NAME:  usbtri

SYMBOL_NAME:  USBPORT!USBPORT_BadRequestFlush+7c

MODULE_NAME:  USBPORT

IMAGE_NAME:  USBPORT.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d868b

Поля SYMBOL_NAME, MODULE_NAME, IMAGE_NAME и DBG_FLR_IMAGE_TIMESTAMP отображают метку символа, модуля, изображения и изображения, соответствующую этой инструкции (если это допустимо), или вызывающему объекту этой инструкции (если это не так).

STACK_COMMAND:  .trap fffffffff8950dfc ; kb

В поле STACK_COMMAND показана команда, используемая для получения STACK_TEXT. Эту команду можно использовать для повторения отображения трассировки стека или изменения для получения связанных сведений стека.

BUCKET_ID:  0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c

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

Сведения о полях FOLLOWUP_NAME и последующих действиях см. в разделе "Поле "Отслеживание" и "Файл triage.ini".

Существуют различные поля, которые могут появиться:

  • Если элемент управления был передан в недопустимый адрес, поле FAULTING_IP будет содержать этот недопустимый адрес. Вместо поля FOLLOWUP_IP поле FAILED_INSTRUCTION_ADDRESS будет отображать дизассемблированное код из этого адреса, хотя этот дизассембли, вероятно, будет бессмысленным. В этой ситуации поля SYMBOL_NAME, MODULE_NAME, IMAGE_NAME и DBG_FLR_IMAGE_TIMESTAMP будут ссылаться на вызывающий объект этой инструкции.

  • Если обработчик заготовит, вы можете увидеть поля SINGLE_BIT_ERROR, TWO_BIT_ERROR или POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Если произошло повреждение памяти, поле CHKIMG_EXTENSION укажет команду расширения !chkimg , которая должна использоваться для изучения.

  • Если в коде драйвера устройства произошла ошибка, его имя может отображаться в поле BUGCHECKING_DRIVER.

Поле подстановки и файл triage.ini

В режиме пользователя и в режиме ядра в поле "Отслеживание" в отображении будут отображаться сведения о владельце текущего кадра стека, если это можно определить. Эта информация определяется следующим образом:

  1. Когда используется расширение !analyze, отладчик начинается с верхнего кадра в стеке и определяет, отвечает ли он за ошибку. Если это не так, следующий кадр анализируется. Этот процесс продолжается до тех пор, пока кадр не будет найден.

  2. Отладчик пытается определить владельца модуля и функции в этом кадре. Если владелец может быть определен, этот кадр считается неисправным.

  3. Если владелец не может быть определен, отладчик передается в следующий кадр стека и т. д., пока владелец не будет определен (или стек полностью проверяется). Первый кадр, владелец которого найден в этом поиске, считается неисправным. Если стек исчерпан без каких-либо сведений, не отображается поле "Отслеживание".

  4. Владелец кадра, неисправного, отображается в поле "Отслеживание". Если используется !analyze -v , поля FOLLOWUP_IP, SYMBOL_NAME, MODULE_NAME, IMAGE_NAME и DBG_FLR_IMAGE_TIMESTAMP будут ссылаться на этот кадр.

Для отображения полезных сведений в поле "Отслеживание" необходимо сначала создать файл triage.ini, содержащий имена владельцев модулей и функций.

Файл triage.ini должен определить владельцев всех модулей, которые могут иметь ошибки. Вы можете использовать информационную строку вместо фактического владельца, но эта строка не может содержать пробелы. Если вы уверены, что модуль не будет ошибаться, можно опустить этот модуль или указать, что он должен быть пропущен. Также можно указать владельцев отдельных функций, что дает процессу триажа еще более подробную детализацию.

Дополнительные сведения о синтаксисе файла triage.ini см. в разделе "Указание владельцев модулей и функций".

Дополнительные методы !анализа

Если сбой или исключение не произошло, !analyze отобразит очень короткий текст, предоставляющий текущее состояние целевого объекта. В некоторых ситуациях может потребоваться принудительно выполнить анализ, как если бы произошел сбой. Используйте !analyze -f для выполнения этой задачи.

В пользовательском режиме, если произошло исключение, но вы считаете, что основная проблема является зависнутым потоком, задайте текущий поток для исследуемого потока, а затем используйте !analyze -hang. Это расширение выполнит анализ стека потоков, чтобы определить, блокируют ли какие-либо потоки другие потоки.

В режиме ядра, если произошла ошибка, но вы считаете, что основная проблема является зависнутой потоком, используйте !analyze -hang. Это расширение будет исследовать блокировки, удерживаемые системой, и сканировать цепочку очередей DPC и отображать любые признаки зависаемых потоков. Если вы считаете, что проблема является взаимоблокировкой ресурсов в режиме ядра, используйте расширение !взаимоблокировки вместе с параметром обнаружения взаимоблокировки средства проверки драйверов.

Вы также можете автоматически игнорировать известные проблемы. Для этого необходимо сначала создать XML-файл, содержащий форматированный список известных проблем. Используйте расширение !analyze -c -load KnownIssuesFile для загрузки этого файла. Затем при возникновении исключения или разрыва используйте расширение !analyze -c . Если исключение соответствует одному из известных проблем, целевой объект возобновляет выполнение. Если целевой объект не возобновляет выполнение, можно использовать !analyze -v для определения причины проблемы.

См. также

Дополнительные сведения см. в этих разделах.

!анализировать

Bug Check Code Reference (Справочник с кодами критических ошибок)

Анализ аварийного дампа с помощью отладчиков Windows (WinDbg)

Анализ файла дампа в режиме ядра с помощью WinDbg