Débogage des fuites de mémoire - DRIVER_VERIFIER_DETECTED_VIOLATION (C4) : 0x62
Le vérificateur de pilotes génère des 0xC4 de vérification des bogues : DRIVER_VERIFIER_DETECTED_VIOLATION avec une valeur de paramètre 1 de 0x62 lorsqu’un pilote décharge sans libérer d’abord toutes ses allocations de pool. Les allocations de mémoire non réduites (également appelées fuites de mémoire) sont une cause courante des performances du système d’exploitation réduites. Ceux-ci peuvent fragmenter les pools système et éventuellement provoquer des plantages système.
Lorsque vous disposez d’un débogueur de noyau connecté à un ordinateur de test exécutant Le vérificateur de pilote, si Le vérificateur de pilotes détecte une violation, Windows se connecte au débogueur et affiche une brève description de l’erreur.
>Débogage des fuites de mémoire au niveau du déchargement du pilote
- Utiliser !analyser pour afficher des informations sur la vérification des bogues
- Utilisez la commande d’extension !verifier 3 pour en savoir plus sur les allocations de pool
- Si vous avez des symboles, vous pouvez localiser l’emplacement dans les fichiers sources où les allocations de mémoire se sont produites
- Examiner le journal des allocations de mémoire
- Résolution des fuites de mémoire
Utiliser !analyser pour afficher des informations sur la vérification des bogues
Comme pour toute vérification de bogue qui se produit, une fois que vous avez le contrôle du débogueur, la meilleure étape consiste à exécuter la commande !analyze -v .
kd> !analyze -v
Connected to Windows 8 9600 x86 compatible target
Loading Kernel Symbols
.................................................................................
Loading User Symbols
.......................
Loading unloaded module list
........
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
DRIVER_VERIFIER_DETECTED_VIOLATION (c4)
A device driver attempting to corrupt the system has been caught. This is
because the driver was specified in the registry as being suspect (by the
administrator) and the kernel has enabled substantial checking of this driver.
If the driver attempts to corrupt the system, bugchecks 0xC4, 0xC1 and 0xA will
be among the most commonly seen crashes.
Arguments:
Arg1: 00000062, A driver has forgotten to free its pool allocations prior to unloading.
Arg2: 9707712c, name of the driver having the issue.
Arg3: 9c1faf70, verifier internal structure with driver information.
Arg4: 00000003, total # of (paged+nonpaged) allocations that weren't freed.
Type !verifier 3 drivername.sys for info on the allocations
that were leaked that caused the bugcheck.
Une 0xC4 de vérification des bogues : DRIVER_VERIFIER_DETECTED_VIOLATION avec une valeur de paramètre 1 (Arg1) de 0x62 est décrite comme suit :
DRIVER_VERIFIER_DETECTED_VIOLATION (C4) Arg1 Arg2 Arg3 Arg4 cause les indicateurs du vérificateur de pilote 0x62 nom du pilote. Nombre total réservé d’allocations qui n’ont pas été libérées, y compris le pool paginé et non paginé. Le pilote se décharge sans libérer d’abord ses allocations de pool. Dans Windows 8.1, cette vérification de bogue se produit également si le pilote est déchargé sans libérer d’abord les éléments de travail (IO_WORKITEM) qu’il avait alloués avec IoAllocateWorkItem. Une vérification des bogues avec ce paramètre se produit uniquement lorsque l’option Suivi du pool est active. Spécifiez le suivi du pool (vérificateur /flags 0x8). L’option Suivi du pool est activée avec des indicateurs standard (vérificateur /standard ).
Utilisez la commande d’extension !verifier 3 pour en savoir plus sur les allocations de pool
Pour cette vérification particulière des bogues, les informations fournies dans le paramètre 4 (Arg4) sont les plus importantes. Arg4 indique le nombre d’allocations qui n’ont pas été libérées. La sortie de la commande !analyze affiche également la commande d’extension du débogueur !verifier que vous pouvez utiliser pour afficher les allocations. La sortie complète de la commande !verifier 3 MyDriver.sys est illustrée dans l’exemple suivant :
kd> !verifier 3 Mydriver.sys
Verify Flags Level 0x000209bb
STANDARD FLAGS:
[X] (0x00000000) Automatic Checks
[X] (0x00000001) Special pool
[X] (0x00000002) Force IRQL checking
[X] (0x00000008) Pool tracking
[X] (0x00000010) I/O verification
[X] (0x00000020) Deadlock detection
[X] (0x00000080) DMA checking
[X] (0x00000100) Security checks
[X] (0x00000800) Miscellaneous checks
[X] (0x00020000) DDI compliance checking
ADDITIONAL FLAGS:
[ ] (0x00000004) Randomized low resources simulation
[ ] (0x00000200) Force pending I/O requests
[ ] (0x00000400) IRP logging
[ ] (0x00002000) Invariant MDL checking for stack
[ ] (0x00004000) Invariant MDL checking for driver
[ ] (0x00008000) Power framework delay fuzzing
[ ] (0x00040000) Systematic low resources simulation
[ ] (0x00080000) DDI compliance checking (additional)
[ ] (0x00200000) NDIS/WIFI verification
[ ] (0x00800000) Kernel synchronization delay fuzzing
[ ] (0x01000000) VM switch verification
[X] Indicates flag is enabled
Summary of All Verifier Statistics
RaiseIrqls 0x0
AcquireSpinLocks 0x0
Synch Executions 0x0
Trims 0x0
Pool Allocations Attempted 0x2db1a
Pool Allocations Succeeded 0x2db1a
Pool Allocations Succeeded SpecialPool 0x2db1a
Pool Allocations With NO TAG 0x0
Pool Allocations Failed 0x0
Current paged pool allocations 0x0 for 00000000 bytes
Peak paged pool allocations 0x0 for 00000000 bytes
Current nonpaged pool allocations 0x3 for 00001058 bytes
Peak nonpaged pool allocations 0x13 for 0004A4A0 bytes
## Driver Verification List
MODULE: 0x84226b28 MyDriver.sys (Loaded)
Pool Allocation Statistics: ( NonPagedPool / PagedPool )
Current Pool Allocations: ( 0x00000003 / 0x00000000 )
Current Pool Bytes: ( 0x00001058 / 0x00000000 )
Peak Pool Allocations: ( 0x00000013 / 0x00000000 )
Peak Pool Bytes: ( 0x0004A4A0 / 0x00000000 )
Contiguous Memory Bytes: 0x00000000
Peak Contiguous Memory Bytes: 0x00000000
Pool Allocations:
Address Length Tag Caller
---------- ---------- ---- ----------
0x982a8fe0 0x00000020 VMdl 0x9a3bf6ac MyDriver!DeviceControlDispatch
0x8645a000 0x00001008 mdrv 0x9a3bf687 MyDriver!DeviceControlDispatch
0x9a836fd0 0x00000030 Vfwi 0x9a3bf6ed MyDriver!GetNecessaryObjects
Par exemple, le pilote, MyDriver.sys, a deux allocations de mémoire et un élément de travail d’E/S qui n’ont pas été correctement libérés. Chaque liste affiche l’adresse de l’allocation actuelle, la taille, la balise de pool utilisée et l’adresse dans le code du pilote où la demande d’allocation a été effectuée. Si des symboles sont chargés pour le pilote en question, il affiche également le nom de la fonction en regard de l’adresse de l’appelant.
Des balises affichées, une seule (pour l’allocation à l’adresse 0x8645a000) a été fournie par le pilote lui-même (mdrv). La balise VMdl est utilisée chaque fois qu’un pilote vérifié par Driver Verifier appelle IoAllocateMdl. De même, la balise Vfwi est utilisée chaque fois qu’un pilote vérifié par Driver Verifier effectue une demande d’allocation d’un élément de travail à l’aide d’IoAllocateWorkItem.
Si vous avez des symboles, vous pouvez localiser l’emplacement dans les fichiers sources où les allocations de mémoire se sont produites
Lorsque des symboles sont chargés pour le pilote, si ces symboles contiennent les informations de numéro de ligne, vous pouvez utiliser la commande ln CallerAddress pour afficher la ligne où l’appel a été effectué. Cette sortie affiche également le décalage dans la fonction qui a effectué l’allocation.
kd> ln 0x9a3bf6ac
d:\coding\wdmdrivers\mydriver\handleioctl.c(50)+0x15
(9a3bf660) MyDriver!DeviceControlDispatch+0x4c | (9a3bf6d0) MyDriver!DeviceControlDispatch
kd> ln 0x9a3bf687
d:\coding\wdmdrivers\mydriver\handleioctl.c(38)+0x12
(9a3bf660) MyDriver!DeviceControlDispatch+0x27 | (9a3bf6d0) MyDriver!DeviceControlDispatch
kd> ln 0x9a3bf6ed
d:\coding\wdmdrivers\mydriver\handleioctl.c(72)+0xa
(9a3bf6d0) MyDriver!GetNecessaryObjects+0x1d | (9a3bf71c) MyDriver!GetNecessaryObjects
Examiner le journal des allocations de mémoire
Le vérificateur de pilotes conserve également un journal circulaire de toutes les allocations de mémoire effectuées dans l’espace noyau lorsque le suivi du pool est activé. Par défaut, les allocations les plus récentes de 65 536 (0x10000) sont conservées. À mesure qu’une nouvelle allocation est effectuée, l’allocation la plus ancienne dans le journal est remplacée. Si les allocations ont été récemment effectuées avant le blocage, il peut être possible d’obtenir des informations supplémentaires sur l’allocation que celles indiquées ci-dessus, en particulier l’adresse de thread et les trames de la pile du noyau au moment de l’allocation.
Ce journal est accessible à l’aide de la commande !verifier 0x80 AddressOfPoolAllocation. Notez que cela répertorie toutes les allocations et les libérations dans le journal pour cette adresse particulière. Pour annuler ou arrêter l’affichage de l’historique des journaux, utilisez les raccourcis clavier : Ctrl + Arrêt avec WinDbg et Ctrl + C avec KD.
kd> !verifier 0x80 0x982a8fe0
Log of recent kernel pool Allocate and Free operations:
There are up to 0x10000 entries in the log.
Parsing 0x00010000 log entries, searching for address 0x982a8fe0.
#
Pool block 982a8fe0, Size 00000020, Thread 9c158bc0
81b250cd nt!IovAllocateMdl+0x3d
8060e41d VerifierExt!IoAllocateMdl_internal_wrapper+0x35
81b29388 nt!VerifierIoAllocateMdl+0x22
9a3bf6ac MyDriver!DeviceControlDispatch+0x4c
9a3bf611 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
80611710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
81b3b635 nt!ViGenericDispatchHandler+0x2d
81b3b784 nt!ViGenericDeviceControl+0x18
81b24b4d nt!IovCallDriver+0x2cc
81703772 nt!IofCallDriver+0x62
8191165e nt!IopSynchronousServiceTail+0x16e
81915518 nt!IopXxxControlFile+0x3e8
kd> !verifier 0x80 0x8645a000
Log of recent kernel pool Allocate and Free operations:
There are up to 0x10000 entries in the log.
Parsing 0x00010000 log entries, searching for address 0x8645a000.
#
Pool block 8645a000, Size 00001000, Thread 9c158bc0
8060ee4f VerifierExt!ExAllocatePoolWithTagPriority_internal_wrapper+0x5b
81b2619e nt!VerifierExAllocatePoolWithTag+0x24
9a3bf687 MyDriver!DeviceControlDispatch+0x27
9a3bf611 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
80611710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
81b3b635 nt!ViGenericDispatchHandler+0x2d
81b3b784 nt!ViGenericDeviceControl+0x18
81b24b4d nt!IovCallDriver+0x2cc
81703772 nt!IofCallDriver+0x62
8191165e nt!IopSynchronousServiceTail+0x16e
81915518 nt!IopXxxControlFile+0x3e8
81914516 nt!NtDeviceIoControlFile+0x2a
kd> !verifier 0x80 0x9a836fd0
Log of recent kernel pool Allocate and Free operations:
There are up to 0x10000 entries in the log.
Parsing 0x00010000 log entries, searching for address 0x9a836fd0.
#
Pool block 9a836fd0, Size 00000030, Thread 88758740
8151713d nt!IovAllocateWorkItem+0x1b
84a133d9 VerifierExt!IoAllocateWorkItem_internal_wrapper+0x29
8151b3a7 nt!VerifierIoAllocateWorkItem+0x16
9a3bf6ed MyDriver!GetNecessaryObjects+0x1d
9a3bf620 MyDriver!NonPNPIRPDispatch0x51
9a3bf05a MyDriver!AllIRPDispatch+0x1a
84a16710 VerifierExt!xdv_IRP_MJ_DEVICE_CONTROL_wrapper+0xd0
8152d635 nt!ViGenericDispatchHandler+0x2d
8152d784 nt!ViGenericDeviceControl+0x18
81516b4d nt!IovCallDriver+0x2cc
810f5772 nt!IofCallDriver+0x62
8130365e nt!IopSynchronousServiceTail+0x16e
81307518 nt!IopXxxControlFile+0x3e8
Résolution des fuites de mémoire
Cette vérification des bogues du vérificateur de pilote est conçue pour empêcher le pilote de fuite de mémoire du noyau. Dans chaque cas, le correctif approprié consiste à identifier les chemins de code existants où les objets alloués ne sont pas libérés et s’assurer qu’ils sont libérés correctement.
Static Driver Verifier est un outil qui analyse le code source du pilote Windows et signale les problèmes possibles en simulant l’exercice de différents chemins de code. Static Driver Verifier est un excellent utilitaire de développement pour aider à identifier ces types de problèmes.
Pour d’autres techniques que vous pouvez utiliser, notamment les scénarios où le vérificateur de pilote n’est pas impliqué, consultez Recherche d’une fuite de mémoire en mode noyau.
Rubriques connexes
Recherche d’une fuite de mémoire en mode noyau
Vérificateur de pilote statique
Gestion d’une vérification des bogues lorsque le vérificateur de pilote est activé