Utilisation de l’extension ! Analyze

La première étape du débogage d’une application ou d’un ordinateur cible bloqué consiste à utiliser la commande d’extension ! analyze .

Cette extension effectue une analyse automatisée d’une grande quantité de données. Les résultats de cette analyse s’affichent dans le Fenêtre Commande du débogueur.

Vous devez utiliser l’option -v pour un affichage des données entièrement détaillé. Pour plus d’informations sur les autres options, consultez la page de référence ! analyser .

Cette rubrique contient les éléments suivants :

  • Exemple User-Mode ! Analyze-v
  • Exemple Kernel-Mode ! Analyze-v
  • Le champ de suivi et le fichier triage.ini
  • Autres méthodes d’analyse

Exemple User-Mode ! Analyze-v

Dans cet exemple, le débogueur est attaché à une application en mode utilisateur qui a rencontré une exception.

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

Debugger SolutionDb Connection::Open failed 80004005

Si vous êtes connecté à Internet, le débogueur tente d’accéder à une base de données de solutions de blocage gérée par Microsoft. Dans ce cas, un message d’erreur s’affiche, indiquant que votre ordinateur n’a pas pu accéder à Internet ou que le site Web ne fonctionnait pas.

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

Le champ FAULTING_IP affiche le pointeur d’instruction au moment de l’erreur.

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

Le champ EXCEPTION_RECORD affiche l’enregistrement d’exception pour ce blocage. Ces informations peuvent également être consultées à l’aide de la commande . EXR (afficher l’enregistrement des exceptions) .

BUGCHECK_STR:  80000003

Le champ BUGCHECK_STR affiche le code de l’exception. Le nom est un impropre : le terme « vérification de bogue » désigne en fait un incident en mode noyau. Dans le cadre du débogage en mode utilisateur, le code de l’exception s’affiche, dans le cas présent, 0x80000003.

DEFAULT_BUCKET_ID:  APPLICATION_FAULT

Le champ DEFAULT_BUCKET_ID affiche la catégorie générale des échecs auxquels ce problème appartient.

PROCESS_NAME:  MyApp.exe

Le champ PROCESS_NAME spécifie le nom du processus qui a déclenché l’exception.

LAST_CONTROL_TRANSFER:  from 01050963 to 77f97704

Le champ LAST_CONTROL_TRANSFER affiche le dernier appel sur la pile. Dans ce cas, le code à l’adresse 0x01050963 a appelé une fonction à 0x77F97704. Vous pouvez utiliser ces adresses avec la commande ln (liste des symboles les plus proches) pour déterminer les modules et les fonctions dans lesquels ces adresses résident.

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

Le champ STACK_TEXT affiche une trace de la pile du composant défaillant.

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

Quand ! analyze détermine l’instruction qui a probablement provoqué l’erreur, elle l’affiche dans le champ FOLLOWUP_IP. Les champs SYMBOL_NAME, MODULE_NAME, IMAGE_NAME et DEBUG_FLR_IMAGE_TIMESTAMP affichent le symbole, le module, le nom de l’image et l’horodatage de l’image correspondant à cette instruction.

STACK_COMMAND:  .ecxr ; kb

Le champ STACK_COMMAND affiche la commande qui a été utilisée pour obtenir le STACK_TEXT. Vous pouvez utiliser cette commande pour répéter l’affichage de la trace de la pile ou la modifier pour obtenir des informations sur la pile associée.

BUCKET_ID:  80000003_MyApp!FatalErrorBox+55

Le champ BUCKET_ID affiche la catégorie spécifique d’échecs à laquelle l’échec actuel appartient. Cette catégorie permet au débogueur de déterminer les autres informations à afficher dans la sortie de l’analyse.

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

Pour plus d’informations sur les champs FOLLOWUP_NAME et suivi, consultez le champ suivi et le fichier triage.ini.

Plusieurs autres champs peuvent s’afficher :

  • Si le contrôle a été transféré à une adresse non valide, le champ FAULTING_IP contient cette adresse non valide. Au lieu du champ FOLLOWUP_IP, le champ FAILED_INSTRUCTION_ADDRESS affiche le code désassemblé à partir de cette adresse, bien que ce code désassemblé soit probablement inutile. Dans ce cas, les champs SYMBOL_NAME, MODULE_NAME, IMAGE_NAME et DEBUG_FLR_IMAGE_TIMESTAMP feront référence à l’appelant de cette instruction.

  • Si le processeur est raté, vous pouvez voir les champs SINGLE_BIT_ERROR, TWO_BIT_ERROR ou POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Si une altération de la mémoire semble s’être produite, le champ CHKIMG_EXTENSION spécifie la commande d’extension ! CHKIMG qui doit être utilisée pour effectuer des recherches.

Exemple Kernel-Mode ! Analyze-v

Dans cet exemple, le débogueur est attaché à un ordinateur qui vient d’être bloqué.

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.

Le premier élément de l’affichage montre le code de vérification de bogue et des informations sur ce type de vérification de bogue. Une partie du texte affiché peut ne pas s’appliquer à cette instance spécifique. Pour plus d’informations sur chaque contrôle de bogue, consultez la section Référence du code de vérification des bogues .

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

Les paramètres de vérification de bogue s’affichent ensuite. Ils sont tous suivis d’une description. Par exemple, le troisième paramètre est 1 et le commentaire qui le suit explique que cela indique qu’une opération d’écriture a échoué.

## Debugging Details:


WRITE_ADDRESS:  00000004 Nonpaged pool

CURRENT_IRQL:  2

Les prochains champs varient en fonction de la nature de l’incident. Dans ce cas, nous voyons des champs WRITE_ADDRESS et CURRENT_IRQL. Il s’agit simplement de reformuler les informations affichées dans les paramètres de vérification de bogue. En comparant l’instruction « pool non paginé » au texte de vérification du bogue qui indique « une tentative d’accès à un pagable (ou une adresse entièrement non valide) », nous pouvons voir que l’adresse n’est pas valide. Dans ce cas, l’adresse non valide était 0x00000004.

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

Le champ FAULTING_IP affiche le pointeur d’instruction au moment de l’erreur.

DEFAULT_BUCKET_ID:  DRIVER_FAULT

Le champ DEFAULT_BUCKET_ID affiche la catégorie générale des échecs auxquels ce problème appartient.

BUGCHECK_STR:  0xD1

Le champ BUGCHECK_STR affiche le code de vérification des bogues que nous avons déjà vu. Dans certains cas, des informations de triage supplémentaires sont ajoutées.

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

Le champ TRAP_FRAME affiche le cadre d’interruption pour ce blocage. Ces informations peuvent également être consultées à l’aide de la commande . Trap (afficher le frame d’interruption) .

LAST_CONTROL_TRANSFER:  from f83206e0 to f832035c

Le champ LAST_CONTROL_TRANSFER affiche le dernier appel sur la pile. Dans ce cas, le code à l’adresse 0xF83206E0 a appelé une fonction à 0xF832035C. Vous pouvez utiliser la commande ln (liste des symboles les plus proches) pour déterminer le module et la fonction desquels ces adresses résident.

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

Le champ STACK_TEXT affiche une trace de la pile du composant défaillant.

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

Le champ FOLLOWUP_IP affiche le code machine de l’instruction qui a probablement provoqué l’erreur.

FOLLOWUP_NAME:  usbtri

SYMBOL_NAME:  USBPORT!USBPORT_BadRequestFlush+7c

MODULE_NAME:  USBPORT

IMAGE_NAME:  USBPORT.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d868b

Les champs SYMBOL_NAME, MODULE_NAME, IMAGE_NAME et DBG_FLR_IMAGE_TIMESTAMP affichent le symbole, le module, l’image et l’horodatage d’image correspondant à cette instruction (si elle est valide) ou à l’appelant de cette instruction (si ce n’est pas le cas).

STACK_COMMAND:  .trap fffffffff8950dfc ; kb

Le champ STACK_COMMAND affiche la commande qui a été utilisée pour obtenir le STACK_TEXT. Vous pouvez utiliser cette commande pour répéter l’affichage de la trace de la pile ou la modifier pour obtenir des informations sur la pile associée.

BUCKET_ID:  0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c

Le champ BUCKET_ID affiche la catégorie spécifique d’échecs à laquelle l’échec actuel appartient. Cette catégorie permet au débogueur de déterminer les autres informations à afficher dans la sortie de l’analyse.

INTERNAL_SOLUTION_TEXT:  https://oca.microsoft.com/resredir.asp?sid=62&State=1

Si vous êtes connecté à Internet, le débogueur tente d’accéder à une base de données de solutions de blocage gérée par Microsoft. Cette base de données contient des liens vers un nombre énorme de pages Web qui contiennent des informations sur les bogues connus. Si une correspondance est trouvée pour votre problème, le champ INTERNAL_SOLUTION_TEXT affiche une URL à laquelle vous pouvez accéder pour plus d’informations.

Followup: usbtri
---------

      This problem has a known fix.
      Please connect to the following URL for details:
      ------------------------------------------------
      https://oca.microsoft.com/resredir.asp?sid=62&State=1

Pour plus d’informations sur les champs FOLLOWUP_NAME et suivi, consultez le champ suivi et le fichier triage.ini :

Plusieurs autres champs peuvent s’afficher :

  • Si le contrôle a été transféré à une adresse non valide, le champ FAULTING_IP contient cette adresse non valide. Au lieu du champ FOLLOWUP_IP, le champ FAILED_INSTRUCTION_ADDRESS affiche le code désassemblé à partir de cette adresse, bien que ce code désassemblé soit probablement inutile. Dans ce cas, les champs SYMBOL_NAME, MODULE_NAME, IMAGE_NAME et DBG_FLR_IMAGE_TIMESTAMP feront référence à l’appelant de cette instruction.

  • Si le processeur est raté, vous pouvez voir les champs SINGLE_BIT_ERROR, TWO_BIT_ERROR ou POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Si une altération de la mémoire semble s’être produite, le champ CHKIMG_EXTENSION spécifie la commande d’extension ! CHKIMG qui doit être utilisée pour effectuer des recherches.

  • Si une vérification de bogue s’est produite dans le code d’un pilote de périphérique, son nom peut s’afficher dans le champ BUGCHECKING_DRIVER.

Le champ de suivi et le fichier triage.ini

En mode utilisateur et en mode noyau, le champ suivi dans l’affichage affiche des informations sur le propriétaire du frame de pile actuel, si cette opération peut être déterminée. Ces informations sont déterminées de la manière suivante :

  1. Lorsque l’extension ! analyze est utilisée, le débogueur commence par le frame supérieur dans la pile et détermine s’il est responsable de l’erreur. Si ce n’est pas le cas, le frame suivant est analysé. Ce processus se poursuit jusqu’à ce qu’une trame en cause soit détectée.

  2. Le débogueur tente de déterminer le propriétaire du module et de la fonction dans ce frame. Si le propriétaire peut être déterminé, ce frame est considéré comme étant défectueux.

  3. Si le propriétaire ne peut pas être déterminé, le débogueur passe au frame de pile suivant, et ainsi de suite, jusqu’à ce que le propriétaire soit déterminé (ou que la pile soit complètement examinée). La première trame dont le propriétaire est trouvé dans cette recherche est considérée comme une erreur. Si la pile est épuisée sans qu’aucune information ne soit trouvée, aucun champ de suivi ne s’affiche.

  4. Le propriétaire du cadre en erreur est affiché dans le champ suivi. Si ! analyze-v est utilisé, les champs FOLLOWUP_IP, SYMBOL_NAME, MODULE_NAME, IMAGE_NAME et DBG_FLR_IMAGE_TIMESTAMP feront référence à ce frame.

Pour afficher des informations utiles dans le champ suivi, vous devez d’abord créer un fichier Triage.ini contenant les noms des propriétaires de module et de fonction.

Le fichier Triage.ini doit identifier les propriétaires de tous les modules susceptibles d’avoir des erreurs. Vous pouvez utiliser une chaîne d’information au lieu d’un propriétaire réel, mais cette chaîne ne peut pas contenir d’espaces. Si vous êtes certain qu’un module ne génère pas d’erreur, vous pouvez omettre ce module ou indiquer qu’il doit être ignoré. Il est également possible de spécifier des propriétaires de fonctions individuelles, ce qui permet au processus de triage d’avoir une granularité encore plus fine.

Pour plus d’informations sur la syntaxe du fichier de Triage.ini, consultez spécification des propriétaires de modules et de fonctions.

Autres méthodes d’analyse

Si vous ne pensez pas que le BUCKET_ID est correct, vous pouvez remplacer le choix de la plage à l’aide de la fonction ! analyze avec le paramètre -D .

Si aucun incident ou aucune exception ne s’est produite, ! analyze affichera un texte très bref indiquant l’état actuel de la cible. Dans certaines situations, vous souhaiterez peut-être forcer l’analyse à avoir lieu comme si un incident se produisait. Utilisez ! analyze-f pour accomplir cette tâche.

En mode utilisateur, si une exception s’est produite mais que vous pensez que le problème sous-jacent est un thread suspendu, définissez le thread actuel sur le thread que vous examinez, puis utilisez ! analyse-Hang. Cette extension effectue une analyse de pile de threads pour déterminer si des threads bloquent d’autres threads.

En mode noyau, si une vérification de bogue s’est produite, mais que vous pensez que le problème sous-jacent est un thread suspendu, utilisez ! analyze-Hang. Cette extension examine les verrous détenus par le système et analyse la chaîne de files d’attente DPC, et affiche toutes les indications des threads bloqués. Si vous pensez que le problème est lié à un blocage de ressources en mode noyau, utilisez l’extension ! Deadlock avec l’option de détection de blocage du vérificateur de pilote.

Vous pouvez également ignorer automatiquement les problèmes connus. Pour ce faire, vous devez d’abord créer un fichier XML contenant une liste mise en forme de problèmes connus. Utilisez l’extension ! analyze-c-LoadKnownIssuesFile pour charger ce fichier. Ensuite, lorsqu’une exception ou un arrêt se produit, utilisez l’extension ! analyze-c . Si l’exception correspond à l’un des problèmes connus, la cible reprend l’exécution. Si la cible ne reprend pas son exécution, vous pouvez utiliser ! analyze-v pour déterminer la cause du problème. Vous trouverez un exemple de fichier XML dans le sous-répertoire sdk\samples\ analyze_continue du répertoire d’installation du débogueur.