Sdílet prostřednictvím


Injektáž selhání na základě zásobníku

Poznámka Pokyny k povolení této funkce platí pouze pro WDK pro Windows 8. Pro Windows 8.1 byla tato funkce integrovaná do nástroje Pro ověřování ovladačů. Na počítačích se systémem Windows 8.1 použijte volbu systematická simulace nízkých prostředků.

Možnost injektáže selhání založená na zásobníku vloží poruchy prostředků do ovladačů v režimu jádra. Tato možnost používá speciální ovladač, KmAutoFail.sys, ve spojení s Driver Verifier proniknutí cesty zpracování chyb ovladače. Testování těchto cest bylo v minulosti velmi obtížné. Možnost injektáže selhání na základě zásobníkové metody injektuje chyby prostředků předvídatelným způsobem, což činí problémy, které nalezne, reprodukovatelnými. Vzhledem k tomu, že cesty k chybám se snadno reprodukují, usnadňuje také ověření oprav těchto problémů.

Abychom vám pomohli určit původní příčinu chyby, poskytuje se rozšíření ladicího programu, které vám může přesně říct, která selhání byla vložena a v jakém pořadí.

Pokud je možnost Stack Based Failure Injection povolena pro konkrétní ovladač, zachytí některá volání z tohoto ovladače do jádra a Ndis.sys. Injektáž selhání pomocí zásobníku se dívá na zásobník volání – konkrétně ve specifické části zásobníku volání, která pochází z ovladače, na kterém je povolena. Pokud se jedná o první případ, kdy se tento zásobník kdy objevil, volání selže podle sémantiky daného volání. Jinak, pokud tento hovor zaznamenal dříve, předá jej beze změny. Injektáž selhání na bázi zásobníku obsahuje logiku, která řeší skutečnost, že ovladač lze nahrát a odpojit vícekrát. Bude moci rozpoznat, že zásobník volání je stejný, i když se ovladač znovu načte do jiné adresy paměti.

aktivovat tuto možnost

Funkci injektáže závad na bázi zásobníku můžete aktivovat pro jeden nebo více ovladačů při nasazení ovladače do testovacího počítače. Při konfiguraci vlastností ověřovatele ovladačů pro projekty balíčků ovladačů můžete vybrat možnost "injekce chyb založené na zásobníku". Chcete-li aktivovat nebo deaktivovat možnost injektáže selhání na základě zásobníku, je nutné restartovat počítač. Můžete také spustit testovací nástroj, který povolí nástroj Driver Verifier a tuto funkci na testovacím počítači.

Důležité Při aktivaci injekce selhání založené na zásobníku na testovacím počítači se ujistěte, že nevyberete také simulaci nízkých prostředků.

  • Použití stránky vlastností Ověření ovladače

    1. Otevřete stránky vlastností balíčku ovladače. Klikněte pravým tlačítkem na projekt balíčku ovladačů v Průzkumníku řešení a vyberte Vlastnosti.
    2. Na stránkách vlastností balíčku ovladače klepněte na tlačítko Vlastnosti konfigurace, klepněte na tlačítko Instalace ovladačea poté klepněte na tlačítko Ovladač ověřit.
    3. Vyberte možnost Povolit ověřování ovladačů. Když na testovacím počítači povolíte nástroj Driver Verifier, můžete povolit nástroj Driver Verifier pro všechny ovladače v počítači, pouze pro projekt ovladače nebo pro seznam zadaných ovladačů.
    4. V části Injektor selhání na základě zásobníkuvyberte (zaškrtněte) Injektáž selhání na základě zásobníku.
    5. Klikněte na Použít nebo OK.
    6. Další informace najdete v tématu Nasazení ovladače do testovacího počítače. Aby se tato možnost aktivoval, musí se testovací počítač restartovat.
  • Použití testu pro povolení a zakázání ověřovatele ovladačů

    1. Můžete také povolit Driver Verifier spuštěním testu nástroje. Postupujte podle pokynů popsaných v Jak otestovat ovladač za běhu pomocí sady Visual Studio. V kategorii testů Všechny testy\Ověřování ovladače vyberte testy Povolit ověření ovladače (může být vyžadován restart) a Zakázat ověření ovladače (může být vyžadován restart).

    2. Vyberte možnosti ověření ovladače kliknutím na název testu Povolit ověření ovladače (je možný restart) v okně Testovací skupina ovladačů.

    3. Vyberte (zaškrtněte) injekci selhání založenou na zásobníku.

    4. Po přidání těchto testů do testovací skupiny můžete testovací skupinu uložit. Aby bylo možné povolit injektáž selhání založenou na zásobníku, spusťte test Povolit ověření ovladače (může vyžadovat restartování) na počítači, který jste nakonfigurovali pro testování.

      Chcete-li deaktivovat nástroj Driver Verifier, spusťte test Zakázat nástroj Driver Verifier (může být vyžadován restart).

použití možnosti injektáže selhání založeného na zásobníku

Jednou z důležitých úvah při testování selhání injekcí na základě zásobníku je to, že většina nalezených chyb způsobí zastavení systému. Může to být poněkud bolestivé, pokud je váš ovladač načítaný při spuštění. Z tohoto důvodu automaticky zakážeme injektáž selhání založenou na zásobníku, pokud je Nástroj pro ověření ovladače zakázán. To znamená, že můžete zakázat injektáž selhání na základě zásobníku při spuštění z ladicího programu zakázáním nástroje Driver Verifier pomocí příkazu !verifier -disable.

Pokud je to možné, při počátečních testech se Stack Based Failure Injection, nastavte váš ovladač tak, aby se nenačítal při startu. Pak můžete spustit několik jednoduchých zátěžových a odlehčovacích testů. Mnoho chyb zjištěných metodou Stack Based Failure Injection se vyskytuje během inicializace nebo ukončování. Opakované načítání a uvolňování ovladačů je dobrým způsobem, jak je najít.

Po provedení všech oprav potřebných k tomu, aby zátěžové a odlehčovací testy proběhly úspěšně, můžete přejít na testování založené na IOCTL, úplné funkční testování a nakonec testování zátěže. Obecně platí, že pokud budete postupovat podle tohoto postupu testu, nebudete během zátěžového testování odhalovat mnoho nových problémů, protože většina cest kódu již byla provedena dříve.

Jak používat rozšíření pro ladicí program SBFI (Stack Based Failure Injection)

Většina problémů zjištěných injektáží selhání na základě zásobníku vede k kontrolám chyb. Pro určení příčiny těchto chyb kódu poskytuje WDK rozšíření ladicího programu pro injektování selhání na základě zásobníku a nezbytné symboly. Postup instalace nainstaluje obojí do systému pro ladění. Výchozí umístění je C:\Program Files (x86)\Windows Kits\8.0\Debuggers\<arch>.

Spustit rozšíření ladicího programu

  • Z příkazového řádku ladicího programu zadejte následující příkaz: !<cesta>\kmautofaildbg.dll.autofail. Například za předpokladu, že rozšíření ladicího programu jsou nainstalována ve složce c:\dbgext a že kmautofail.pdb je v symbolové cestě, zadejte následující příkaz:

    !c:\dbgext\kmautofaildbg.dll.autofail
    

Tím se vypíší informace do ladicího programu, zobrazující zásobníky volání z nejnovějších vložených selhání. Každá položka vypadá nějak takto a je vzata z reálného testování. V následujícím příkladu je na Mydriver.sys povolena injekce selhání založená na zásobníku.

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

V horní části výstupu spočítá pořadové číslo počet chyb, které se vloží. Tento příklad ukazuje druhou chybu vloženou během tohoto testovacího běhu. ID procesu je 0, takže se jednalo o systémový proces. IRQL je 2, takže se volá na úrovni odeslání.

KmAutoFail je ovladač pro injektáž selhání založenou na zásobníku. Název funkce KmAutoFail označuje volání funkce z Mydriver.sys, které bylo zachyceno a do nějž byla vložena chyba. Zde byla funkce, která selhala, ExAllocatePoolWithTag. Všechny funkce v KmAutoFail, které zachycují volání Ntoskrnl.sys nebo Ndis.sys, používají tuto konvenci pojmenování. Dále vidíme volací zásobník, ve kterém je testovaný ovladač (Mydriver.sys). Toto je část zásobníku volání, která se používá k stanovení jedinečnosti zásobníku volání. Každá položka vypíše rozšíření ladicího programu tak bude v této části zásobníku volání jedinečná. Zbytek zásobníku volání označuje, kdo volal řidiče. Hlavním významem je to, zda je ovladač volán z uživatelského režimu (pomocí IOCTL) nebo z ovladače režimu jádra.

Všimněte si, že pokud ovladač vrátil chybu ze své rutiny DriverEntry, bude pokus o opětovné načtení obvykle probíhat v jiném umístění paměti. V takovém případě bude zásobník volání z dřívějšího umístění pravděpodobně obsahovat „nesmysly“ místo informací o zásobníku z ovladače. Ale to není problém; říká vám, že řadič správně zvládl tuto vloženou chybu.

Tato další položka ukazuje volání ovladače prostřednictvím IOCTL v uživatelském režimu. Poznamenejte si ID procesu a úroveň IRQ. Vzhledem k tomu, že Mydriver.sys je ovladač filtru NDIS, prošel IOCTL skrz Ndis.sys. Všimněte si, že nt!NtDeviceIoControlFile je v zásobníku. Všechny testy, které spustíte na ovladači používajícím IOCTLs, projdou touto funkcí.

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

Analýza výsledků injektáže selhání založeného na zásobníku

Provádíte testy na vašem ovladači a najednou narazíte na problém. S největší pravděpodobností se jednalo o kontrolu chyb, ale mohlo by to také kvůli tomu, že počítač přestal reagovat. Jak zjistíte příčinu? Za předpokladu, že se jedná o kontrolu chyb, nejprve pomocí výše uvedeného rozšíření vyhledejte seznam vložených selhání a pak použijte příkaz ladicího programu: !analyze –v.

Nejběžnější kontrola chyb je způsobena tím, že není kontrolováno, zda bylo přidělení úspěšné. V tomto případě je zásobník analýzy chyb pravděpodobně téměř stejný jako u posledního selhání, které bylo vloženo. V určitém okamžiku po neúspěšném přidělení (často na dalším řádku) bude ovladač přistupovat k ukazateli null. Tento typ chyby je velmi snadné opravit. Někdy je neúspěšné přidělení o jednu nebo dvě pozice výše v seznamu, ale tento typ problému je stále docela snadné najít a opravit.

Během čištění dochází k druhé nejběžnější kontrole chyb. V tomto případě ovladač pravděpodobně zjistil selhání přidělení a přešel k vyčištění; ale během vyčišťování ovladač nezkontroloval ukazatel a znovu přistupoval k nulovému ukazateli. Úzce související případ spočívá v tom, že je možné volat funkci čištění dvakrát. Pokud vyčištění nenastaví ukazatel na strukturu na hodnotu null poté, co ji uvolní, druhá funkce vyčištění se pokusí uvolnit strukturu podruhé, což vede ke kontrole chyb.

Chyby, které způsobují, že počítač přestane reagovat, jsou těžší diagnostikovat, ale postup při jejich ladění je podobný. Příčinou těchto chyb jsou často problémy s počtem referencí nebo otáčkovým zámkem. Driver Verifier naštěstí zachytí mnoho problémů se spinlockem dříve, než by mohly vést k potížím. V těchto případech vstupte do ladicího programu a pomocí rozšíření ladicího programu vypište seznam chyb, které byly vloženy injekcí selhání založenou na zásobníku. Rychlý pohled na kód kolem nejnovějších selhání může ukázat referenční počet, který je zachycen před selháním, ale není uvolněn po. Pokud ne, vyhledejte vlákno ve vašem ovladači, které čeká na zámek otáčení, nebo pro jakýkoli počet odkazů, který je zřejmě chybný.