Partager via


.jdinfo (Utiliser JIT_DEBUG_INFO)

La commande .jdinfo utilise une structure JIT_DEBUG_INFO comme source de l’exception et du contexte pour le débogage juste-à-temps (JIT). L’adresse de la structure est passée à la commande .jdinfo à l’aide du paramètre %p spécifié dans l’entrée de Registre AeDebug.

Pour plus d’informations sur les clés de Registre utilisées, consultez Activation du débogage postmortem. Pour plus d’informations sur les contextes d’inscription, consultez Modification des contextes.

.jdinfo Address 

Paramètres

Adresse
Spécifie l’adresse de la structure JIT_DEBUG_INFO. L’adresse de la structure est passée à la commande .jdinfo à l’aide du paramètre %p spécifié dans l’entrée de Registre AeDebug.

Environnement

Les modes

Mode utilisateur

Targets

Live, vidage de la mémoire

Platforms

Tous

Exemple

Cet exemple montre comment l’entrée de Registre AeDebug peut être configurée pour utiliser WinDbg comme débogueur JIT.

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

Ensuite, lorsqu’un incident se produit, le débogueur JIT configuré est appelé et le paramètre %p est utilisé pour passer l’adresse de la structure JIT_DEBUG_INFO à la commande .jdinfo exécutée après le démarrage du débogueur.

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=????????

Notes

La commande .jdinfo utilise les informations de Registre AeDebug introduites dans Windows Vista. Pour plus d’informations sur les clés de Registre utilisées, consultez Activation du débogage postmortem. La commande .jdinfo prend l’adresse d’un JIT_DEBUG_INFO que le système a configuré pour AeDebug et définit le contexte à l’exception qui a provoqué le blocage.

Vous pouvez utiliser la commande .jdinfo au lieu de -g dans AeDebug pour que votre débogueur soit défini sur l’état AeDebug sans nécessiter d’exécution.

Cet état peut être avantageux, car dans des conditions habituelles, lorsqu’une exception en mode utilisateur se produit, la séquence suivante se produit :

  1. Le système d’exploitation Microsoft Windows arrête l’exécution de l’application.

  2. Le débogueur postmortem est démarré.

  3. Le débogueur s’attache à l’application.

  4. Le débogueur émet une commande « Go ». (Cette commande est provoquée par le -g dans la clé AeDebug .)

  5. La cible tente d’exécuter et peut ou non rencontrer la même exception.

  6. Cette exception se décompose dans le débogueur.

Plusieurs problèmes peuvent se produire en raison de ces événements :

  • Les exceptions ne se répètent pas toujours, éventuellement en raison d’une condition temporaire qui n’existe plus lorsque l’exception est redémarrée.

  • Un autre événement, tel qu’une autre exception, peut se produire. Il n’existe aucun moyen de savoir s’il est identique à l’événement d’origine.

  • L’attachement d’un débogueur implique l’injection d’un nouveau thread, qui peut être bloqué si un thread tient le verrou du chargeur. L’injection d’un nouveau thread peut être une perturbation significative du processus.

Si vous utilisez -c .jdinfo au lieu de -g dans votre clé AeDebug , aucune exécution ne se produit. Au lieu de cela, les informations d’exception sont récupérées à partir de la structure JIT_DEBUG_INFO à l’aide de la variable %p.

Par exemple, considérez la clé AeDebug suivante.

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

L’exemple suivant est encore moins invasif. Le commutateur -pv provoque l’attachement du débogueur de manière nonvasive, qui n’injecte aucun nouveau thread dans la cible.

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

Si vous utilisez cette option nonvasive, la sortie du débogueur ne termine pas le processus. Vous pouvez utiliser la commande .kill (Kill Process) pour mettre fin au processus.

Si vous souhaitez l’utiliser pour le débogage de fichiers de vidage, vous devez utiliser .dump /j pour ajouter la structure JIT_DEBUG_INFO à votre fichier de vidage, lorsque le fichier de vidage est créé.

La structure JIT_DEBUG_INFO est définie comme suit.

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;

Vous pouvez utiliser la commande dt pour afficher la structure JIT_DEBUG_INFO.

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

Affichage de l’enregistrement d’exception, de la pile des appels et du lastEvent à l’aide de WinDbg

Une fois la commande .jdinfo utilisée pour définir le contexte au moment de l’échec, vous pouvez afficher l’enregistrement d’exception retourné par .jdinfo, la pile des appels et le dernier événement, comme indiqué ci-dessous, pour examiner la cause.

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)