Dela via


Stackbaserad feleffektsimulering

Obs Instruktionerna för att aktivera den här funktionen gäller endast för WDK för Windows 8. För Windows 8.1 har den här funktionen integrerats i drivrutinsverifieraren. På datorer som kör Windows 8.1 använder du alternativet Systematisk simulering av låga resurser.

Alternativet Stackbaserad felinjektion injicerar resursfel i kernellägesdrivrutiner. Det här alternativet använder en särskild drivrutin, KmAutoFail.sys, tillsammans med drivrutinsverifierare för att penetrera drivrutinsfelhanteringsvägar. Att testa de här sökvägarna har historiskt sett varit mycket svårt. Alternativet Stackbaserad felinmatning matar in resursfel på ett förutsägbart sätt, vilket gör de problem som hittas reproducerbara. Eftersom felsökvägarna är enkla att återskapa blir det också enkelt att verifiera korrigeringar av dessa problem.

För att hjälpa dig att identifiera grundorsaken till felet tillhandahålls ett felsökningstillägg som kan berätta exakt vilka felaktigheter som har införts och i vilken ordning.

När alternativet Stack-baserad felinmatning är aktiverat på en specifik drivrutin fångas vissa anrop från drivrutinen upp till kerneln och Ndis.sys. Stackbaserad felinmatning tittar på anropsstacken – särskilt på den del av anropsstacken som kommer från drivrutinen som den är aktiverad på. Om det här är första gången den någonsin har sett den stacken, kommer det att misslyckas med anropet enligt anropets semantik. Annars, om den har sett det samtalet förut, kommer den att låta det gå igenom orört. Stackbaserad felinmatning innehåller logik för att hantera det faktum att en drivrutin kan läsas in och tas bort flera gånger. Det kommer att känna igen att en anropsstack är densamma även om drivrutinen omladdas till en annan minnesplats.

Aktivera det här alternativet

Du kan aktivera funktionen stackbaserad felinmatning för en eller flera drivrutiner när du distribuerar en drivrutin till en testdator. Du kan välja alternativet Stackbaserad felinmatning när du konfigurerar egenskaperna för drivrutinsverifierare för drivrutinspaketprojekt. Du måste starta om datorn för att aktivera eller inaktivera alternativet Stack-baserad felinmatning. Du kan också köra ett testverktyg för att aktivera drivrutinsverifierare och den här funktionen på testdatorn.

Viktigt När du aktiverar stackbaserad felinmatning på testdatorn ska du inte också välja simulering med låga resurser.

  • Använda egenskapssidan för Drivrutinsverifieraren

    1. Öppna egenskapssidorna för drivrutinspaketet. Högerklicka på drivrutinspaketprojektet i Solution Explorer och välj Egenskaper.
    2. På egenskapssidorna för drivrutinspaketet klickar du på Konfigurationsegenskaper, klickar på Drivrutinsinstallationoch klickar sedan på drivrutinsverifierare.
    3. Välj Aktivera drivrutinsverifierare. När du aktiverar drivrutinsverifierare på testdatorn kan du välja att aktivera drivrutinsverifierare för alla drivrutiner på datorn, endast för drivrutinsprojektet eller för en lista över angivna drivrutiner.
    4. Under stackbaserad felinjektorväljer du (kontrollera) Stackbaserad felinmatning.
    5. Klicka på Använd eller OK.
    6. Mer information finns i Distribuera en drivrutin till en testdator. Testdatorn måste startas om för att aktivera det här alternativet.
  • Använd testet Aktivera och inaktivera drivrutinsverifieraren

    1. Du kan också aktivera drivrutinsverifierare genom att köra ett verktygstest. Följ anvisningarna i Så här testar du en drivrutin vid körning med Visual Studio. Under testkategorin Alla tester\Drivrutinsverifierare väljer du Aktivera drivrutinsverifierare (eventuell omstart krävs) och Inaktivera drivrutinsverifierare (eventuell omstart krävs) tester.

    2. Välj alternativen för drivrutinsverifierare genom att klicka på namnet på Aktivera drivrutinsverifierare (eventuell omstart krävs) testet i Driver Test Group-fönstret.

    3. Välj (kontrollera) Stackbaserad felinmatning.

    4. När du har lagt till dessa tester i en testgrupp kan du spara testgruppen. Om du vill aktivera stackbaserad felinmatning kör du Aktivera drivrutinsverifierare (eventuell omstart krävs) test på den dator som du har konfigurerat för testning.

      Om du vill inaktivera drivrutinsverifieraren kör du Inaktivera drivrutinsverifierare (eventuell omstart krävs) test.

med alternativet Stackbaserad felinmatning

En viktig faktor när du testar med Stack Based Failure Injection är att de flesta buggar som hittas resulterar i en buggkontroll. Detta kan visa sig vara något smärtsamt om drivrutinen är en bootladdad drivrutin. Därför inaktiverar vi automatiskt stackbaserad felinmatning om drivrutinsverifieraren är inaktiverad. Det innebär att du kan inaktivera stackbaserad felinmatning vid start från felsökningsprogrammet genom att inaktivera drivrutinsverifieraren med hjälp av kommandot !verifier – inaktivera.

Om det är möjligt konfigurerar du drivrutinen för dina första tester med stackbaserad felinmatning så att den inte läses in vid starttillfället. Du kan sedan köra några enkla belastnings- och avlastningstester. Många av buggarna som hittas av Stack Based Failure Injection inträffar under initiering eller rensning. Att läsa in och lossa din drivrutin upprepade gånger är ett bra sätt att hitta dem.

När du har gjort de korrigeringar som krävs för att lasta av testerna ska lyckas kan du gå vidare till IOCTL-baserad testning, fullständig funktionell testning och slutligen stresstestning. Om du följer den här testprogressionen kommer du i allmänhet inte att upptäcka många nya problem under stresstestning eftersom de flesta kodsökvägarna redan har körts innan detta.

Med hjälp av SBFI-felsökningstillägget (Stack Based Failure Injection)

De flesta problem som påträffas med Stack-baserad felinmatning resulterar i buggkontroller. För att fastställa orsaken till dessa kodbuggar tillhandahåller WDK tillägget stackbaserad felinjektionsfelsökning och nödvändiga symboler. Installationsproceduren kommer att installera båda på ditt felsökningssystem. Standardplatsen är C:\Program Files (x86)\Windows Kits\8.0\Debuggers\<arch>.

Kör felsökningstillägget

  • I kommandotolken för felsökning skriver du följande kommando: !<sökväg>\kmautofaildbg.dll.autofail. Om du till exempel antar att felsökartillägg installeras på c:\dbgext och att kmautofail.pdb finns i symbolsökvägen, anger du följande kommando:

    !c:\dbgext\kmautofaildbg.dll.autofail
    

Detta skickar information till din debugger som visar anropsstackarna från de senaste inmatade felen. Varje post ser ut ungefär så här, hämtad från en riktig testkörning. I följande exempel aktiveras Stapelorienterad Felinjektion på Mydriver.sys

Sequence: 2, Test Number: 0, Process ID: 0, Thread ID: 0
                 IRQ Level: 2, HASH: 0xea98a56083aae93c
 0xfffff8800129ed83 kmautofail!ShimHookExAllocatePoolWithTag+0x37
 0xfffff88003c77566 mydriver!AddDestination+0x66
 0xfffff88003c5eeb2 mydriver!ProcessPacketDestination+0x82
 0xfffff88003c7db82 mydriver!ProcessPacketSource+0x8b2
 0xfffff88003c5d0d8 mydriver!ForwardPackets+0xb8
 0xfffff88003c81102 mydriver!RoutePackets+0x142
 0xfffff88003c83826 mydriver!RouteNetBufferLists+0x306
 0xfffff88003c59a76 mydriver!DeviceSendPackets+0x156
 0xfffff88003c59754 mydriver!ProcessingComplete+0x4a4
 0xfffff88001b69b81 systemdriver2!ProcessEvent+0x1a1
 0xfffff88001b3edc4 systemdriver1!CallChildDriver+0x20
 0xfffff88001b3fc0a systemdriver1!ProcessEvent+0x3e
 0xfffff800c3ea6eb9 nt!KiRetireDpcList+0x209
 0xfffff800c3ea869a nt!KiIdleLoop+0x5a

Längst upp i utdata räknar sekvensnumret antalet fel som matas in. Det här exemplet visar det andra felet som matas in under den här testkörningen. Process-ID:t är 0, så det här var systemprocessen. IRQL är 2, så detta anropas på sändningsnivå.

KmAutoFail är stackbaserad failure injection-drivrutin från stacken. KmAutoFail-funktionsnamnet anger vilket funktionsanrop från Mydriver.sys som avlyssnades och felinjicerades. Här var funktionen som misslyckades ExAllocatePoolWithTag. Alla funktioner i KmAutoFail som fångar upp anrop till Ntoskrnl.sys eller Ndis.sys använder den här namngivningskonventionen. Därefter ser vi anropsstacken där drivrutinen testas (Mydriver.sys). Det här är den del av anropsstacken som används för att fastställa stackens unika värde. Varje post som dumpas av felsökningstillägget kommer därför att vara unik i den här delen av anropsstacken. Resten av anropsstacken anger vem som anropade drivrutinen. Det viktigaste är om drivrutinen anropas från användarläge (med hjälp av en IOCTL) eller från en kernellägesdrivrutin.

Observera att om en drivrutin har returnerat ett fel från sin DriverEntry- rutin, sker normalt ett nytt inläsningsförsök på en annan minnesplats. I så fall innehåller anropsstacken från den tidigare platsen förmodligen "skräp" i stället för stackinformation från drivrutinen. Men detta är inte ett problem; den talar om för dig att drivrutinen hanterade det inmatade felet korrekt.

Det nästa inlägget visar ett anrop till drivrutinen genom en IOCTL från användarmod. Observera process-ID:t och IRQ-nivån. Eftersom Mydriver.sys är en NDIS-filterdrivrutin, kom IOCTL via Ndis.sys. Observera att nt! NtDeviceIoControlFile finns på stacken. Alla tester som du kör på drivrutinen som använder IOCTLs går igenom den här funktionen.

Sequence: 5, Test Number: 0, Process ID: 2052, Thread ID: 4588
                 IRQ Level: 0, HASH: 0xecd4650e9c25ee4
 0xfffff8800129ed83 kmautofail!ShimHookExAllocatePoolWithTag+0x37
 0xfffff88003c6fb39 mydriver!SendMultipleOids+0x41
 0xfffff88003c7157b mydriver!PvtDisconnect+0x437
 0xfffff88003c71069 mydriver!NicDisconnect+0xd9
 0xfffff88003ca3538 mydriver!NicControl+0x10c
 0xfffff88003c99625 mydriver!DeviceControl+0x4c5
 0xfffff88001559d93 NDIS!ndisDummyIrpHandler+0x73
 0xfffff88001559339 NDIS!ndisDeviceControlIrpHandler+0xc9
 0xfffff800c445cc96 nt!IovCallDriver+0x3e6
 0xfffff800c42735ae nt!IopXxxControlFile+0x7cc
 0xfffff800c4274836 nt!NtDeviceIoControlFile+0x56
 0xfffff800c3e74753 nt!KiSystemServiceCopyEnd+0x13

Att analysera resultatet av stackbaserad felsimulering

Du kör dina tester på din drivrutin och plötsligt stöter du på ett problem. Troligtvis var detta en buggkontroll, men det kan också bero på att datorn inte svarar. Hur hittar du orsaken? Förutsatt att det är en buggkontroll använder du först tillägget ovan för att hitta listan över inmatade fel och använder sedan felsökningskommandot: !analyze –v.

Den vanligaste felkontrollen orsakas av att en allokering inte har lyckats. I det här fallet är stacken från buggkontrollanalysen förmodligen nästan identisk med den för det senaste inmatade felet. Någon gång efter den misslyckade allokeringen (ofta nästa rad) kommer drivrutinen att komma åt nullpekaren. Den här typen av bugg är mycket enkel att åtgärda. Ibland är den misslyckade allokeringen en eller två i listan, men den här typen är fortfarande mycket lätt att hitta och åtgärda.

Den näst vanligaste felkontrollen sker under rensningen. I det här fallet upptäckte drivrutinen förmodligen allokeringsfelet och hoppade till rensningen. men under rensningen kontrollerade drivrutinen inte pekaren och använde återigen en null-pekare. Ett nära relaterat fall är där rensning kan anropas två gånger. Om rensningen inte ställer in pekaren på en struktur till null när den frigörs, kommer den andra gången rensningsfunktionen anropas att försöka frigöra strukturen en andra gång, vilket resulterar i en buggkontroll.

Fel som gör att datorn inte svarar är svårare att diagnostisera, men proceduren för att felsöka dem är liknande. Dessa fel orsakas ofta av problem med referensantal eller spinnlås. Lyckligtvis kommer Driver Verifier att upptäcka många spinlock-problem innan de leder till bekymmer. I dessa fall kan du bryta dig in i felsökningsprogrammet och använda felsökningstillägget för att dumpa listan över fel som har matats in av stackbaserad felinmatning. En snabb titt på koden kring de senaste felen kan visa ett referensantal som tas före felet men inte släpps efter. Om det inte är fallet, leta efter en tråd i din drivrutin som väntar på ett spinnlås, eller efter något referensantal som tydligt är fel.