Stack-alapú hibainjektálás

Megjegyzés A funkció engedélyezésére vonatkozó utasítások csak a Windows 8 WDK-ra vonatkoznak. Windows 8.1 esetén ez a funkció integrálva lett az Illesztőprogram-ellenőrzőbe. Windows 8.1 rendszerű számítógépeken használja a Szisztematikus alacsony erőforrások szimulációja lehetőséget.

A Stack Based Failure Injection beállítás erőforráshibákat injektál kernel módú illesztőprogramokban. Ez a beállítás egy speciális KmAutoFail.sysillesztőprogramot használ a Illesztőprogram-ellenőrzővel együtt az illesztőprogram hibakezelési útvonalainak behatolásához. Ezeknek az útvonalaknak a tesztelése történelmileg nagyon nehéz volt. A Veremalapú hibainjektálási beállítás kiszámítható módon injektálja az erőforráshibákat, ami reprodukálhatóvá teszi a talált problémákat. Mivel a hibavonalak könnyen reprodukálhatók, a hibák kijavításának ellenőrzése is egyszerűvé válik.

A hiba kiváltó okának meghatározásához rendelkezésre áll egy hibakereső bővítmény, amely pontosan meg tudja állapítani, hogy mely hibákat adták be, és milyen sorrendben.

Ha a Stack Based Failure Injection beállítás engedélyezve van egy adott illesztőprogramhoz, az elfog néhány hívást az adott illesztőprogramból a kernelbe és az Ndis.sys felé. A veremalapú hibainjektálás a hívásvermet vizsgálja – pontosabban a hívásverem azon részét, amely abból az illesztőprogramból származik, amelyen engedélyezve van. Ha ez az első alkalom, hogy valaha is látta ezt a vermet, a hívás szemantikája szerint meghiúsul a hívás. Ellenkező esetben, ha már látta ezt a hívást, akkor érintetlenül továbbítja azt. A stackalapú hibainjektálás logikát tartalmaz annak a ténynek a kezelésére, hogy az illesztőprogramok többször is betölthetők és eltávolíthatók. Felismeri, hogy a hívásverem azonos, még akkor is, ha az illesztőprogramot egy másik memóriahelyre töltik be.

A beállítás aktiválása

Egy vagy több illesztőprogram esetében aktiválhatja a verem alapú hibainjektálási funkciót, amikor illesztőprogramot telepít egy tesztszámítógépre. Amikor konfigurálja az Illesztőprogram-ellenőrző tulajdonságait az illesztőprogram-csomag projektekhez, választhatja a Veremalapú hibainjektálási lehetőséget. Ahhoz, hogy aktiválja vagy inaktiválja a Stack Based Failure Injection beállítást, újra kell indítania a számítógépet. Tesztsegédprogramot futtathat az Illesztőprogram-ellenőrző engedélyezéséhez, valamint ezt a funkciót a tesztszámítógépen.

Fontos Amikor aktiválja a verem alapú hibainjektálást a tesztszámítógépen, ügyeljen arra, hogy ne válassza az alacsony erőforrás-szimulációt.

  • Driver Verifier tulajdonságlap használata

    1. Nyissa meg az illesztőprogram-csomag tulajdonságlapjait. Kattintson a jobb gombbal az illesztőprogram-csomag projektre Megoldáskezelő, és válassza a Tulajdonságoklehetőséget.
    2. Az illesztőprogram-csomag tulajdonságlapjain kattintson Konfiguráció tulajdonságaielemre, kattintson Illesztőprogram telepítéseelemre, majd kattintson Illesztőprogram-ellenőrzőelemre.
    3. Válassza az Illesztőprogram-ellenőrző engedélyezéselehetőséget. Ha engedélyezi az Illesztőprogram-ellenőrzőt a tesztszámítógépen, engedélyezheti az Illesztőprogram-ellenőrzőt a számítógépen lévő összes illesztőprogramhoz, csak az illesztőprogram-projekthez vagy a megadott illesztőprogramok listájához.
    4. A Veremalapú hibainjektor területen válassza ki és jelölje be a Veremalapú hibainjektálás lehetőséget.
    5. Kattintson az Alkalmazás vagy az OK gombra.
    6. További információ: Illesztőprogram üzembe helyezése tesztszámítógépen. A tesztszámítógépnek újra kell indulnia a beállítás aktiválásához.
  • Az Illesztőprogram-ellenőrző teszt engedélyezése és letiltása

    1. Az illesztőprogram-ellenőrzőt segédprogram-teszt futtatásával is engedélyezheti. Kövesse az Illesztőprogramok futásidőben való tesztelése a Visual Studiohasználatával című cikkben leírt utasításokat. A Minden teszt\Illesztőprogram-ellenőrző tesztkategória alatt válassza ki az Illesztőprogram-ellenőrző engedélyezése (lehetséges újraindítás szükséges) és Az illesztőprogram-ellenőrző letiltása (lehetséges újraindítás szükséges) teszteket.

    2. Az illesztőprogram-ellenőrző beállításainak kiválasztásához kattintson az Illesztőprogram-ellenőrző engedélyezése (lehetséges újraindítás szükséges) teszt nevére az Illesztőprogram-tesztcsoport ablakban.

    3. Válassza a veremalapú hibainjektálást (jelölje be).

    4. Miután hozzáadta ezeket a teszteket egy tesztcsoporthoz, mentheti a tesztcsoportot. A stackalapú hibainjektálás engedélyezéséhez futtassa az Illesztőprogram-ellenőrző engedélyezése (lehetséges újraindítás szükséges) tesztet a teszteléshez konfigurált számítógépen.

      Az Illesztőprogram-ellenőrző inaktiválásához futtassa az Az illesztőprogram-ellenőrző letiltása (lehetséges újraindítás szükséges) tesztet.

Veremalapú hibainjektálási lehetőség használata

A Stack-alapú hibainjektálással végzett tesztelés egyik fontos szempontja, hogy a talált hibák többsége hibaellenőrzést eredményez. Ez kissé fájdalmasnak bizonyulhat, ha az illesztőprogram rendszerindításkor betöltődő. Emiatt automatikusan letiltjuk a stackalapú hibainjektálást, ha az illesztőprogram-ellenőrző le van tiltva. Ez azt jelenti, hogy a rendszerindítás során a hibakeresőből letilthatja a stack-alapú hibainjektálást az Illesztőprogram-ellenőrző letiltásával a !verifier –disable parancs használatával.

Ha lehetséges, a stackalapú hibainjektálással végzett kezdeti tesztekhez állítsa be az illesztőprogramot, hogy a rendszerindításkor ne legyen betöltve. Ezután futtathat néhány egyszerű terhelési és kiürítési tesztet. A Stack Based Failure Injection által talált hibák közül sok az inicializálás vagy a törlés során fordul elő. A meghajtó ismételt telepítése és eltávolítása jó módszer ezek megtalálására.

A terheléseltérési tesztek sikeres végrehajtásához szükséges javítások elvégzése után továbbléphet az IOCTL-alapú tesztelésre, a teljes funkcionális tesztelésre és végül a stressztesztelésre. Általánosságban elmondható, hogy ha ezt a teszt előrehaladását követi, nem fog sok új problémát feltárni a stressztesztelés során, mivel a kód elérési útjainak többsége már korábban is végrehajtásra került.

Stack Based Failure Injection (SBFI) hibakereső bővítmény használata

A Stack-alapú hibainjektálással kapcsolatos problémák többsége hibaellenőrzéseket eredményez. A kódhibák okának meghatározásához a WDK biztosítja a Stack Based Failure Debugger bővítményt és a szükséges szimbólumokat. A telepítési eljárás mindkettőt telepíti a hibakereső rendszerre. Az alapértelmezett hely a C:\Program Files (x86)\Windows Kits\8.0\Debuggers\<arch>.

Hibakereső bővítmény futtatása

  • A hibakereső parancssorából írja be a következő parancsot: !<elérési út>\kmautofaildbg.dll.autofail. Tegyük fel például, hogy a hibakereső bővítmények a c:\dbgext helyen vannak telepítve, és hogy a kmautofail.pdb a szimbólum elérési útján található. Ekkor a következő parancsot kell megadni:

    !c:\dbgext\kmautofaildbg.dll.autofail
    

Ez adatokat küld a hibakeresőnek, és megjeleníti a legutóbbi beszúrt hibák hívásveremeit. Minden bejegyzés a következőhöz hasonlóan néz ki, egy valódi tesztfuttatásból származik. Az alábbi példában a Stack alapú hibainjektálás engedélyezve van a Mydriver.sys-n.

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

A kimenet tetején a sorozatszám megszámolja az injektált hibák számát. Ez a példa a tesztfuttatás során beszúrt második hibát mutatja be. A folyamatazonosító 0, ezért ez volt a rendszerfolyamat. Az IRQL 2, ezért ezt a diszpécserszinten hívják.

A veremben található KmAutoFail egy stackalapú hiba injektálására szolgáló meghajtó. A KmAutoFail függvény neve azt jelzi, hogy a Mydriver.sys melyik függvényhívást fogták el, és melyik hibát injektálták. Itt az a függvény, amelyik nem sikerült, a ExAllocatePoolWithTagvolt. A KmAutoFail minden olyan függvénye, amely Ntoskrnl.sys vagy Ndis.sys hívásokat fogad, használja ezt az elnevezési konvenciót. Ezután látható a hívásverem, amelyen az illesztőprogram tesztelése történik (Mydriver.sys). Ez a hívásverem azon része, amely a verem egyediségének meghatározására szolgál. Így a hibakereső bővítmény által dobott összes bejegyzés egyedi lesz a hívásverem ezen részében. A hívási verem többi része azt jelzi, hogy ki hívta a meghajtót. Ennek fő jelentősége az, hogy az illesztőprogramot felhasználói módban (IOCTL használatával) vagy kernel módú illesztőprogramból hívják-e.

Vegye figyelembe, hogy ha egy illesztőprogram hibát adott vissza a DriverEntry rutinból, az újratöltési kísérlet általában más memóriahelyen történik. Ebben az esetben a korábbi helyről származó hívásverem valószínűleg "szemetet" tartalmaz, nem pedig az illesztőprogramtól származó veremadatokat. De ez nem probléma; azt jelzi, hogy a meghajtó helyesen kezelte az injektált hibát.

Ez a következő bejegyzés bemutatja az illesztőprogram felé irányuló hívást egy IOCTL-lel a felhasználói módból. Jegyezze fel a folyamatazonosítót és az IRQ-szintet. Mivel a Mydriver.sys egy NDIS szűrőillesztő, az IOCTL a(z) Ndis.sys-en keresztül érkezett. Figyelje meg, hogy az nt!NtDeviceIoControlFile a veremben található. Az illesztőprogramon futtatott bármely teszt, amely IOCTL-eket használ, ezen a függvényen keresztül megy.

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

Stack-alapú hibainjektálás eredményeinek elemzése

A tesztjeit az illesztőprogramján futtatja, és hirtelen problémába ütközik. Ez valószínűleg hibaellenőrzés volt, de az is lehet, hogy a számítógép nem válaszol. Hogyan találja meg az okot? Ha hibaellenőrzésről van szó, először használja a fenti bővítményt az injektált hibák listájának megkereséséhez, majd használja a hibakereső parancsot: !analyze –v.

A leggyakoribb hibaellenőrzést az okozza, hogy nem ellenőrzi a foglalás sikerességét. Ebben az esetben a hibaellenőrzési elemzésből származó veremnyom valószínűleg majdnem megegyezik az utolsó szándékosan előidézett hibáéval. A sikertelen foglalást követően (ami gyakran a következő sorban történik), az illesztőprogram egy ponton hozzáfér a null mutatóhoz. Ez a hibatípus nagyon könnyen javítható. Néha a sikertelen foglalás egy vagy két helyezéssel a listán feljebb van, de ez a típus mégis nagyon könnyen megtalálható és javítható.

A második leggyakoribb hibaellenőrzés a törlés során történik. Ebben az esetben az illesztőprogram valószínűleg észlelte a foglalási hibát, és a törlésre ugrott; de a törlés során az illesztőprogram nem ellenőrizte az egérmutatót, és ismét elért egy null mutatót. Egy szorosan kapcsolódó eset, amikor a törlést kétszer lehet meghívni. Ha a törlés nem állítja az egérmutatót null értékre a felszabadítás után, a második alkalommal, amikor a tisztítási függvényt hívják, a rendszer másodszor is megpróbálja felszabadítani a struktúrát, ami hibaellenőrzést eredményez.

Azokat a hibákat, amelyek miatt a számítógép nem válaszol, nehezebb diagnosztizálni, de a hibakeresési eljárás hasonló. Az ilyen hibákat gyakran a hivatkozásszám vagy a spin lock mechanizmus problémái okozzák. Szerencsére a Driver Verifier sok spin lock hibát észlel, mielőtt azok problémákat okoznának. Ezekben az esetekben bontsa be a hibakeresőt, és használja a hibakereső bővítményt a stackalapú hibainjektálás által beszúrt hibák listájának kiírásához. Ha gyorsan áttekinti a legújabb hibákra vonatkozó kódot, megjelenhet egy hivatkozási szám, amelyet a hiba előtt vettek fel, de utána nem adták ki. Ha nem, keressen egy szálat az illesztőprogramban, amely egy spinlock-ra vár, vagy olyan hivatkozási számot, amely egyértelműen helytelen.