Dela via


Felsöka minnesläckor – DRIVER_VERIFIER_DETECTED_VIOLATION (C4): 0x62

Drivrutinsverifieraren genererar Felkontroll 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION med parameter 1-värdet 0x62 när en drivrutin avladdas utan att först frigöra alla sina poolallokeringar. Minnesallokeringar som inte har använts (kallas även minnesläckor) är en vanlig orsak till lägre operativsystemprestanda. Dessa kan fragmenta systempoolerna och så småningom orsaka systemkrascher.

När du har ett kernelfelsökare anslutet till en testdator som kör drivrutinsverifieraren, om drivrutinsverifieraren upptäcker en överträdelse, bryter Sig Windows in i felsökningsprogrammet och visar en kort beskrivning av felet.

>Felsöka minnesläckor vid avlastning av drivrutin

Använd !analyze för att visa information om buggkontrollen

När det inträffar en buggkontroll och du har kontroll över felsökningsprogrammet, är det bästa första steget att köra kommandot !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.

En felkontroll 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION med värdet parameter 1 (Arg1) för 0x62 beskrivs på följande sätt:

DRIVER_VERIFIER_DETECTED_VIOLATION (C4) Arg1 Arg2 Arg3 Arg4 Orsak Driver Verifier flaggor 0x62 Namn på drivrutinen. Totalt antal reserverade allokeringar som inte har frigjorts, inklusive både växlingsbara och icke-sidiga pooler. Drivrutinen lossar utan att först frigöra sina poolallokeringar. I Windows 8.1 inträffar även den här felkontrollen om drivrutinen lossade utan att först frigöra några arbetsobjekt (IO_WORKITEM) som den hade allokerat med IoAllocateWorkItem. En felkontroll med den här parametern inträffar endast när alternativet Poolspårning är aktivt. Ange poolspårning (verifierare/flaggor 0x8). Alternativet Poolspårning är aktiverat med standardflaggor (verifierare /standard ).

Använd kommandot !verifier 3-tillägget för att ta reda på mer om poolallokeringarna

För just den här buggkontrollen är informationen i parameter 4 (Arg4) den viktigaste. Arg4 visar antalet allokeringar som inte frigjorts. Utdata från kommandot !analyze visar också kommandot !verifier debugger extension som du kan använda för att visa vad dessa allokeringar var. De fullständiga utdata från kommandot !verifier 3 MyDriver.sys visas i följande exempel:

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

I detta exempel har drivrutinen MyDriver.systvå minnesallokeringar och ett I/O-arbetsobjekt som inte har frigjorts korrekt. Varje lista visar adressen för den aktuella allokeringen, storleken, pooltaggen som används och adressen i drivrutinskoden där begäran om allokering gjordes. Om symboler läses in för drivrutinen i fråga visas även namnet på funktionen bredvid anroparens adress.

Av de taggar som visas angavs endast en (för allokeringen på adressen 0x8645a000) av själva drivrutinen (mdrv). Taggen VMdl används när en drivrutin som verifieras av drivrutinsverifieraren anropar IoAllocateMdl. På samma sätt används taggen Vfwi när en drivrutin som verifieras av drivrutinsverifieraren gör en begäran om att allokera ett arbetsobjekt med hjälp av IoAllocateWorkItem.

Om du har symboler kan du hitta var i källfilerna minnesallokeringarna inträffade

När symboler läses in för drivrutinen kan du använda kommandot lnCallerAddress för att visa raden där anropet gjordes om dessa symboler innehåller information om radnumret. Denna utdata visar också offseten i funktionen som gör allokeringen.

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

Granska loggen för minnesallokeringar

Drivrutinsverifieraren har också en cirkulär logg över alla minnesallokeringar som görs i kernelutrymmet när poolspårning är aktiverat. Som standard behålls de senaste 65 536 (0x10000) allokeringarna. När en ny allokering görs skrivs den äldsta allokeringen i loggen över. Om allokeringarna gjordes nyligen före kraschen kan det vara möjligt att få ytterligare information om allokeringen än vad som visas ovan, särskilt trådadressen och ramarna för kernelstacken vid tidpunkten för allokeringen.

Du kan komma åt den här loggen med hjälp av kommandot !verifier 0x80AddressOfPoolAllocation. Observera att detta kommer att lista alla allokeringar och frigörningar i loggen för just denna adress. Om du vill avbryta eller stoppa visningen av logghistoriken använder du kortkommandona: Ctrl + Bryt med WinDbg och Ctrl + C med 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

Åtgärda minnesläckor

Den här felkontrollen för drivrutinsverifieraren är utformad för att förhindra att drivrutinen läcker kernelminne. I varje fall är rätt korrigering att identifiera befintliga kodsökvägar där de allokerade objekten inte frigörs och se till att de frigörs korrekt.

Static Driver Verifier är ett verktyg som söker igenom källkoden för Windows-drivrutinen och rapporterar om möjliga problem genom att simulera träning av olika kodsökvägar. Static Driver Verifier är ett fantastiskt verktyg att använda under utvecklingstiden som hjälper dig att identifiera sådana problem.

Andra tekniker som du kan använda, inklusive scenarier där drivrutinsverifieraren inte är involverad, finns i Hitta en Kernel-Mode minnesläcka.

Hitta en Kernel-Mode minnesläcka

Statisk drivrutinsverifierare

Windows-felsökning

Hantera en felkontroll när drivrutinsverifieraren är aktiverad