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


.jdinfo (использование JIT_DEBUG_INFO)

Команда Jdinfo использует JIT_DEBUG_INFO структуру в качестве источника исключения и контекста для отладки JIT. Адрес структуры передается команде Jdinfo с помощью параметра %p, указанного в записи реестра AeDebug.

Дополнительные сведения об используемых разделах реестра см. в разделе "Включение отладки postmortem". Дополнительные сведения о контекстах регистрации см. в разделе "Изменение контекстов".

.jdinfo Address 

Параметры

Адрес
Задает адрес структуры JIT_DEBUG_INFO. Адрес структуры передается команде Jdinfo с помощью параметра %p, указанного в записи реестра AeDebug.

Среда

Режимы

Режим пользователя

Целевые объекты

Динамический, аварийный дампа

Платформы

Все

Пример

В этом примере показано, как можно настроить запись реестра AeDebug для использования WinDbg в качестве отладчика JIT.

Debugger = "Path\WinDbg.EXE -p %ld -e %ld -c ".jdinfo 0x%p"

Затем при сбое вызывается настроенный отладчик JIT, а параметр %p используется для передачи адреса структуры JIT_DEBUG_INFO команде Jdinfo , выполняемой после запуска отладчика.

nMicrosoft (R) Windows Debugger Version 10.0.10240.9 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach
Executable search path is: 
...
ModLoad: 00000000`68a20000 00000000`68ac3000   C:\WINDOWS\WinSxS\amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.9247_none_08e394a1a83e212f\MSVCR90.dll
(153c.5d0): Break instruction exception - code 80000003 (first chance)
Processing initial command '.jdinfo 0x00000000003E0000'
ntdll!DbgBreakPoint:
00007ffc`81a986a0 cc              int     3
0:003> .jdinfo 0x00000000003E0000
----- Exception occurred on thread 0:15c8
ntdll!ZwWaitForMultipleObjects+0x14:
00007ffc`81a959a4 c3              ret

----- Exception record at 00000000`003e0028:
ExceptionAddress: 00007ff791d81014 (CrashAV_x64!wmain+0x0000000000000014)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000001
   Parameter[1]: 0000000000000000
Attempt to write to address 0000000000000000

----- Context record at 00000000`003e00c0:
rax=0000000000000000 rbx=0000000000000000 rcx=00007ffc81a954d4
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000001
rip=00007ff791d81014 rsp=00000000006ff8b0 rbp=0000000000000000
 r8=00000000006ff808  r9=0000000000000000 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
CrashAV_x64!wmain+0x14:
00007ff7`91d81014 45891b          mov     dword ptr [r11],r11d ds:00000000`00000000=????????

Замечания

Команда Jdinfo использует сведения о реестре AeDebug, представленные в Windows Vista. Дополнительные сведения об используемых разделах реестра см. в разделе "Включение отладки postmortem". Команда Jdinfo принимает адрес JIT_DEBUG_INFO, настроенный системой для AeDebug , и задает контекст исключения, вызвавшего сбой.

Вы можете использовать команду Jdinfo вместо -g в AeDebug, чтобы отладчик задал состояние AeDebug без необходимости выполнения.

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

  1. Операционная система Microsoft Windows останавливает выполнение приложения.

  2. Запущен отладчик postmortem.

  3. Отладчик подключается к приложению.

  4. Отладчик выдает команду Go. (Эта команда вызвана ключом -g в ключе AeDebug.)

  5. Целевой объект пытается выполнить и может или не столкнуться с тем же исключением.

  6. Это исключение разбивается на отладчик.

Существует несколько проблем, которые могут возникнуть из-за этих событий:

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

  • Может произойти другое событие, например другое исключение. Нет способа знать, идентично ли оно исходному событию.

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

Если вы используете -c .jdinfo вместо -g в ключе AeDebug , выполнение не происходит. Вместо этого сведения об исключении извлекаются из структуры JIT_DEBUG_INFO с помощью переменной %p.

Например, рассмотрим следующий ключ AeDebug .

ntsd -p %ld -e %ld -c ".jdinfo 0x%p"

Следующий пример является еще менее инвазивным. Переключатель -pv приводит к тому, что отладчик прикрепляет невиновно, что не внедряет новые потоки в целевой объект.

ntsd -pv -p %ld -e %ld -c ".jdinfo 0x%p"

Если вы используете этот неинсивный параметр, выход из отладчика не завершает процесс. Для завершения процесса можно использовать команду kill (Kill Process ).

Если вы хотите использовать это для отладки файлов дампа, следует использовать .dump /j , чтобы добавить структуру JIT_DEBUG_INFO в файл дампа при создании файла дампа.

Структура JIT_DEBUG_INFO определяется следующим образом.

typedef struct _JIT_DEBUG_INFO {
    DWORD dwSize;
    DWORD dwProcessorArchitecture;
    DWORD dwThreadID;
    DWORD dwReserved0;
    ULONG64 lpExceptionAddress;
    ULONG64 lpExceptionRecord;
    ULONG64 lpContextRecord;
} JIT_DEBUG_INFO, *LPJIT_DEBUG_INFO;

Для отображения структуры JIT_DEBUG_INFO можно использовать команду dt.

0: kd> dt JIT_DEBUG_INFO
nt!JIT_DEBUG_INFO
   +0x000 dwSize           : Uint4B
   +0x004 dwProcessorArchitecture : Uint4B
   +0x008 dwThreadID       : Uint4B
  +0x00c dwReserved0      : Uint4B
   +0x010 lpExceptionAddress : Uint8B
   +0x018 lpExceptionRecord : Uint8B
   +0x020 lpContextRecord  : Uint8B

Просмотр записи исключений, стека вызовов и LastEvent с помощью WinDbg

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

0:000> .jdinfo  0x00000000003E0000
----- Exception occurred on thread 0:15c8
ntdll!NtWaitForMultipleObjects+0x14:
00007ffc`81a959a4 c3              ret

----- Exception record at 00000000`003e0028:
ExceptionAddress: 00007ff791d81014 (CrashAV_x64!wmain+0x0000000000000014)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000001
   Parameter[1]: 0000000000000000
Attempt to write to address 0000000000000000
...

0:000> k
  *** Stack trace for last set context - .thread/.cxr resets it
# Child-SP          RetAddr           Call Site
00 00000000`006ff8b0 00007ff7`91d811d2 CrashAV_x64!wmain+0x14 [c:\my\my_projects\crash\crashav\crashav.cpp @ 14]
01 00000000`006ff8e0 00007ffc`7fa38364 CrashAV_x64!__tmainCRTStartup+0x11a [f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crtexe.c @ 579]
02 00000000`006ff910 00007ffc`81a55e91 KERNEL32!BaseThreadInitThunk+0x14
03 00000000`006ff940 00000000`00000000 ntdll!RtlUserThreadStart+0x21

0:000> .lastevent
Last event: 153c.5d0: Break instruction exception - code 80000003 (first chance)
  debugger time: Thu Sep  8 12:55:08.968 2016 (UTC - 7:00)