- Az IRQL végrehajtási prioritásokat definiál és szintenként maszkolja a megszakításokat, a DISPATCH felett az IRQL-t adja meg, nem a szál prioritását.
- sok BSOD A 0xA/0xD1 hibákat általában lapozható vagy érvénytelen memóriához való magas IRQL-lel történő hozzáférés, valamint helytelen címek vagy lapozható kód okozza.
- A WinDbg és a Driver Verifier kulcsfontosságú: használd az !analyze, !irql, ln, .trap, !pool és !address függvényeket, és vizsgáld meg az 1., 3. és 4. paramétereket.
- En illesztőprogramok, megakadályozza a lapozási hibákat magas IRQL-értékek esetén, nem lapozható memóriát és spin lockokat használ; a felhasználó számára frissíti/elszigeteli a problémás illesztőprogramokat.
Ha valaha is láttál kék képernyőt olyan üzenetekkel, mint például IRQL_NOT_LESS_OR_EQUAL o DRIVER_IRQL_NOT_LESS_OR_EQUALvalószínűleg találkoztál már egy olyan fogalommal, amely a meghajtóprogramok világán kívül kevéssé ismert: az IRQL-lel (Interrupt Request Level). Windows, ez a megszakítási prioritási szint elsőbbséget élvez a szál prioritásával szemben, amikor a rendszer egy bizonyos küszöbérték felett van, és ennek közvetlen következményei vannak a stabilitásra.
A következő sorokban megtalálod UNA teljes útmutató és spanyolul Spanyolországból arról, hogy mi az IRQL, és hogyan működik, miért okoz kék képernyőket, hogyan diagnosztizálható a WinDbg problémája, és mit kell tenni, ha felhasználóként tapasztalja a hibát, vagy kernel módú illesztőprogramokat fejleszt. Térjünk a lényegre.
Mi az IRQL (megszakítási kérési szint) Windows rendszerben?
Windows alatt a Az IRQL meghatározza a prioritást hardver ahol a processzor működik bármikor. A Windows illesztőprogram-modellen (WDM) belül az alacsony IRQL-lel futó kódot megszakíthatja a magasabb IRQL-lel futó kód. Valójában egyetlen többmagos számítógépen minden CPU-nak eltérő IRQL-je lehet, ami bonyolítja a szinkronizálást.
Van egy fő szabály: Amikor egy CPU PASSIVE_LEVEL feletti IRQL-lel fut, akkor csak egy még magasabb IRQL-lel végzett tevékenység előzheti meg.Ez megszervezi a felhasználói kód, a kernelfüggvények, a késleltetett hívók (DPC-k) és az eszközmegszakítás-szolgáltatási rutinok (ISR-ek) együttélését.
Szintek és prioritások: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL és DIRQL
Általánosságban, x86-on 0 és 31 közötti IRQL értékeket használunk; x64-en 0 és 15 között.A gyakorlati jelentés ugyanaz: az IRQL 0 (PASSIVE_LEVEL) az, ahol a normál felhasználói kód és számos illesztőprogram-függvény végrehajtódik; APC és oldalhibák Általában az IRQL 1-hez (APC_LEVEL) vannak leképezve; az IRQL 2 (DISPATCH_LEVEL) magában foglalja a szálütemezőt és a DPC-ket. A DISPATCH_LEVEL feletti szintek az eszközmegszakítások (DIRQL néven ismertek) és más belső felhasználások, például a HIGH_LEVEL számára vannak fenntartva.
A járművezetői ökoszisztémában Sok gyakori rutin fut a DISPATCH_LEVEL szinten.például a DPC és a StartIo. Ez a kialakítás biztosítja, hogy miközben az egyikük belső sorokat vagy más megosztott erőforrásokat érint, egy másik, ugyanazon a szinten lévő rutin nem előzi meg azt az adott CPU-n, mivel az elővételi szabály csak a magasabb szinteken engedélyezi a megszakításokat.
A DISPATCH_LEVEL és a profilalkotási/magas szintek között van hely a következőknek: minden eszköz hardveres megszakításai (DIRQL)Egy eszköz IRQL-je határozza meg a prioritását más eszközökkel szemben. A WDM-illesztőprogram ezt az IRQL-t az IRP_MJ_PNP során kapja meg az IRP_MN_START_DEVICE segítségével. Ez az eszköz IRQL-je nem egy globális, fix érték, hanem egy adott megszakítási vonalhoz társított érték.
IRQL vs. szálprioritás
Célszerű nem összekeverni a fogalmakat: A szál prioritása határozza meg, hogy az ütemező mikor indít elővételt és melyik szál fut le; az IRQL szabályozza, hogy milyen típusú tevékenység hajtható végre, és mely megszakítások legyenek maszkolva. A DISPATCH_LEVEL felett nincs szálváltás: az IRQL szabályoz, nem a szál prioritása.
IRQL és lapozás: Amit nem szabad tenni
Az IRQL emelésének közvetlen hatása, hogy a rendszer nem tudja kezelni az oldalhibákatAranyszabály: a DISPATCH_LEVEL szint felett futó kód nem okozhat laphibákat. A gyakorlatban ez azt jelenti, hogy ezek a rutinok és az általuk érintett adatok nem lapozható memóriában kell lennieEzenkívül bizonyos kernel segítők korlátozzák a használatukat az IRQL alapján: például, KeWaitForSingleObject
A DISPATCH_LEVEL csak akkor hívható meg, ha nincs blokkolás (nulla időtúllépés), és nem nulla időtúllépés esetén a DISPATCH_LEVEL érték alatt kell lennie.
Az IRQL implicit és explicit ellenőrzése
Az idő nagy részében maga a rendszer hívja meg a rutinjaidat a megfelelő IRQL-lel azért, hogy mit kellene tenniük. Az IRP-k küldőrutinjai PASSIVE_LEVEL-en futnak (bármely segítőt blokkolhatnak vagy meghívhatnak), a StartIo és a DPC a DISPATCH_LEVEL-en futnak a megosztott sorok védelme érdekében, az ISR-ek pedig DIRQL-en.
Ha explicit módon kell szabályoznod, Az IRQL-t a következővel növelheted és csökkentheted: KeRaiseIrql
y KeLowerIrql
Van egy nagyon jól bevált rövidítés: KeRaiseIrqlToDpcLevel()
visszaadja az előző IRQL-t, és a DISPATCH_LEVEL értéken hagyja. Fontos: Soha ne csökkentse az IRQL-t az alá az érték alá, amelyen a rendszer meghívta Önt; a szinkronizáció megszakítása nagyon komoly versenyidőszakokat nyithat meg.
IRQL-lel kapcsolatos kék képernyő hibák: IRQL_NOT_LESS_OR_EQUAL és DRIVER_IRQL_NOT_LESS_OR_EQUAL
Két klasszikus hibaellenőrzés kapcsolódik ezekhez a problémákhoz: IRQL_NOT_LESS_OR_EQUAL (0xA) y DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)Mindkettő egy lapozható (vagy érvénytelen) cím elérésére tett kísérletet jelez túl magas IRQL-lel. Ez általában annak köszönhető, hogy az illesztőprogramok helytelen címeket használnak, hibás mutatókat dereferenciálnak, vagy lapozható kódot nem megfelelő szinteken hajtanak végre.
A konkrét esetben DRIVER_IRQL_NOT_LESS_OR_EQUAL (0x000000D1), a paraméterek nagyon informatívak: 1) a hivatkozott memória címe; 2) az IRQL abban az időben; 3) a hozzáférés típusa (0 olvasás, 1 írás, 2/8 végrehajtás); 4) a memóriára hivatkozó utasítás címe. A hibakeresővel a következőket használhatod: ln
a 4. paraméteren Sorold fel a legközelebbi szimbólumot és tudd, melyik függvény futott.
Gyakori okok, amelyekre érdemes odafigyelni
A konkrét kódon túl vannak ismétlődő minták is. Érvénytelen mutató dereferenciálása DISPATCH_LEVEL vagy magasabb szintre Ez biztos recept a katasztrófára. A lapozható adatokhoz való hozzáférés ezen a szinten, vagy a lapozható kód (pl. egy lapozhatóként megjelölt függvény) végrehajtása szintén elindítja a hibakeresést.
Egyéb gyakori esetek közé tartozik egy már letöltött illesztőprogram függvényének meghívása (függő függvénymutató), vagy közvetve, érvénytelen függvénymutatón keresztül hívható meg. Gyakran, ha a rendszer képes azonosítani egy modult, a neve megjelenik magán a kék képernyőn, és a rendszer el is menti a modult. KiBugCheckDriver
, elérhető a következővel: dx KiBugCheckDriver
a WinDbg-től.
Egy gyakorlati részlet: A legtöbb D1/A esetében az igazi probléma nem maga az IRQL., hanem inkább a hivatkozott memóriacímet. Ezért az 1., 3. és 4. paraméterek kulcsfontosságúak a diagnózis fókuszálásához.
Diagnosztika a WinDbg segítségével: Hasznos parancsok és paraméterek olvasása
Hogy ezeken az ügyeken dolgozhassak, A WinDbg a legfontosabb eszköz, és ha a BSOD megemlíti ntoskrnl.exe Ez az információ sok támpontot nyújt arra vonatkozóan, hogy a hiba a kernel alrendszerben van-e. Kezdjük azzal, hogy !analyze -v
hogy összefoglalót kapjon a hibakeresésről, a veremről, és ha szerencsénk van, az érintett modulról. Ha a memóriakép tartalmaz egy rögzítési keretet, .trap
a meghibásodott CPU kontextusába helyez.
sok parancsok a halomból, mint k
, kb
, kc
, kd
, kp
, kP
, kv
Különböző szintű visszakövetési részletességet mutatnak. ln
a 4. paraméternél kihagyhatja arra az utasításra, amely a memóriára hivatkozott és szerezd meg a közeli szimbólumot. És ha gyanítod, hogy a prioritási szint a megszakítás előtt fut, !irql
megmutatja a célprocesszorhoz mentett IRQL-t (pl. DISPATCH_LEVEL).
Az 1. paraméter irányának elemzéséhez !pool
Meg fogja mondani, hogy egy lapozott készlethez tartozik-e; !address
y !pte
mélyedj el az adott terület memóriatérképének feltárásában. Használhatod a memória megjelenítési parancsok hogy megvizsgálja a hozzáférni próbált tartalmat. Végül, u
, ub
, uu
lehetővé teszi a szétszerelést a 4-es paraméter címe körül.
Ne felejtsük el, lm t n
a betöltött modulok listázása y !memusage
az emlékezet általános állapotára vonatkozóan. Ha KiBugCheckDriver
van valamije, dx KiBugCheckDriver
Visszaadja az Unicode modul nevét: egy tipikus példában a hibakeresés során a „Wdf01000.sys” volt látható az érintett illesztőprogramként.
Rendszereszközök: Illesztőprogram-ellenőrző, Eseménynapló és Diagnosztika
El Illesztőprogram-ellenőrző Valós időben vizsgálja az illesztőprogramok viselkedését, és hibákat kényszerít ki, ha helytelen erőforrás-használatot észlel (például a pool), kivételt generálva a kód problémás területének elkülönítésére. A következővel indul: verifier
-tól parancssor és célszerű a lehető legkisebb illesztőprogram-készletet kiválasztani, hogy elkerüljük a túlzott többletterhelést.
Ha nem látod magad a WinDbg-vel, alapvető intézkedéseket alkalmaz: Ellenőrizze az Eseménynapló rendszernaplóját egy adott eszközre/illesztőprogramra mutató hibák után; frissítse vagy tiltsa le a kék képernyő által jelzett illesztőprogramot; ellenőrizze a hardver kompatibilitását a Windows verziójával; és használja a Windows memóriadiagnosztikát, ha RAM-hibára gyanakszik. Ezek a műveletek, bár egyszerűek, rengeteg ügyet oldanak meg.
Valós esetek: Amikor a BSOD-ok véletlenszerűnek tűnnek
Windows 10 Pro rendszerű felhasználó (AMD Ryzen 5 3400G CPU, GPU NVIDIA GeForce GTX 1660 Ti és Gigabyte B450 AORUS PRO WIFI alaplap, 16 GB RAM) időszakosan "IRQL_LESS_OR_NOT_EQUAL" képernyők jelentkeztek. Már frissítettem a legfontosabb illesztőprogramokat (hálózat, grafika), telepítettem az összes Windows-frissítést, és futtattam a memóriaeszközt, mindezt anélkül, hogy bármilyen problémát észleltem volna.
Ilyen forgatókönyvekben A következő lépés a dumpok elemzése a WinDbg segítségével. és keressen mintákat: a leeséskor lezajló folyamatokat (például explorer.exe
), grafikus felület modulok (win32kfull.sys
) és olyan függvények, mint xxxProcessNotifyWinEvent
megjelenni a veremben. Bár ez a modul Windows, a kiváltó ok gyakran egy harmadik féltől származó illesztőprogram (grafikus, bemeneti, overlay, rögzítő kártyák), amely nem megfelelő IRQL-lel használja a memóriát, és a hiba a következőn belül keletkezik: win32k
.
A gyakorlati ajánlás itt a következő: Átfedő szoftver ideiglenes letiltása (rögzítés, GPU OSD), agresszív szoftverperifériák illesztőprogramjai (egerek/billentyűzetek makrókkal) és grafikus illesztőprogramok béta verziói, és leszűkítheti a kört. A Driver Verifier használata a gyanús eseteken segíthet leszűkíteni a problémát egy áttekinthetőbb megoldással.
Egy nagyon gyakori hálózati minta: az ndis.sys nem mindig a hibás
Egy másik tipikus eset: képernyőkép az ndis.sys fájllal (a Windows hálózati rétege). Egy valódi számítógépen a rendszer azonnal összeomlana indításkor. A gyakorlati megoldás az volt, hogy a következőbe bootoltak be: Biztonsági mód hálózati funkciók nélkül nyissa meg a Eszközkezelő és tiltsa le az adaptereket a „Hálózati adapterek” alatt a probléma elkülönítéséhez.
Abban a csapatban volt egy Realtek PCIe GBE családvezérlő és egy Atheros AR5007GMindkettő kikapcsolásával kiderült, hogy a valódi ok a athrx.sys
(Atheros), bár a kék képernyő említésre került ndis.sys
A kiírás megerősítette ezt: a verem áthaladt ndis!NdisFreeTimerObject
de a bűnös modul az volt athrx.sys
A végső korrekció az volt, Távolítsa el az eszközt, és telepítse a frissített hivatalos illesztőprogramokat Az Atheros gyártójának weboldaláról. Tanulság: A BSOD-ban idézett modul az érintett alrendszer része lehet, nem a forrás.
Tipikus támogatási válasz és gyors lépések felhasználók számára
Egy őszinte támogató párbeszéd során egy technikus így válaszolt: „Elnézést kérek a kellemetlenségért. Lehet, hogy illesztőprogram-, memória- vagy víruskereső probléma van. Kérjük, frissítse az illesztőprogramokat, és ha a probléma továbbra is fennáll, futtassa a memóriadiagnosztikát.”Ez alapvető, de érvényes tanács; azonban ha a hibák továbbra is fennállnak, érdemes további ellenőrző és memóriaelemzési módszerekkel dolgozni.
Nem műszaki felhasználók számára egy ésszerű protokoll a következő lenne: 1) Rendszeresemények ellenőrzése, 2) Kulcsfontosságú illesztőprogramok frissítése (chipset/hálózat/grafika), 3) RAM ellenőrzése az integrált eszközzel, 4) teszt csomagtartó tiszta külső szoftver nélkül, ami hookokat illeszt be a kernelbe/grafikus felhasználói felületbe, és 5) használd a Verifier-t külső illesztőprogramokon, ha semmi sem világos.
Ajánlott gyakorlatok illesztőprogram-fejlesztők számára
Ha fejlesztés alatt állsz és belebotlasz a D1/A-ba, ellenőrizd, hogy a a futó rutin nincs lapozhatóként megjelölve Ne hívj lapozható függvényeket DISPATCH_LEVEL vagy magasabb szintű futás közben. Ez magában foglalja a lapozható szakaszokban található adatokra való hivatkozások elkerülését és a DDK-ban leírt kernel helperekre vonatkozó IRQL-korlátozások betartását.
A megosztott adatok szinkronizálásához alkalmazza a „megosztott adatokhoz mindig ugyanazon a magas IRQL-lel férjen hozzá” szabályt és szükség esetén használjon spin lockokat. Többprocesszoros rendszereken az IRQL önmagában nem garantálja a kizárást a különböző CPU-k között; a spin lockok megemelik az IRQL-t (DISPATCH_LEVEL-re) és koordinálják a hozzáférést a magok között. Ha érzékeny hardverregisztereken kell dolgoznia, KeSynchronizeExecution
segít a kritikus szakaszok végrehajtásában a megfelelő DIRQL-lel.
Amikor a terv megköveteli az IRQL emelését, USA KeRaiseIrqlToDpcLevel
a DISPATCH_LEVEL esetében vagy KeRaiseIrql
gondosan, mentve az előző IRQL-t, és pontosan visszaállítva azt a következővel: KeLowerIrql
Menj a bemeneti IRQL alá, akár csak egy pillanatra is, Ez egy komoly szinkronizációs hiba.
Kapcsolat a megszakításokkal és a hardverrel
Az IRQL az a mechanizmus, amellyel a Windows a parancsok megszakítják a prioritásokat és bizonyos belső feladatokatArchitekturális szinten olyan fogalmakhoz kapcsolódik, mint az „Interrupt”, a „Interrupt handler” vagy a „Interrupt priority level”, klasszikus platformokon pedig a Programozható megszakításvezérlő (PIC)Más rendszerekben a prioritásvezérlés olyan mechanizmusokon keresztül fejeződik ki, mint például pls en Unix; az általános elképzelés ugyanaz: ki szakíthat félbe kit.
Haladó hibakeresési tippek
A verem által jelzett helyeken win32kfull!xxxProcessNotifyWinEvent
0xA/0xD1 hibaellenőrzéssel, kontextus vizsgálata a következővel: .process
y .thread
(ha van ilyen), tekintse meg az olyan folyamatokat, mint a explorer.exe
en !process 0 1
és ellenőrizd az átfedéseket és a grafikus felhasználói felület (GUI) interakciós illesztőprogramjait. A probléma sokszor Egy harmadik fél által megrontott emlék, ami ezen az útvonalon bukkan fel..
Ne felejtsd el ellenőrizni az IRQL-t a következővel: !irql
, és kontraszt: ha a DISPATCH_LEVEL (2) szinten vagy, és a 3-as paraméter olvasást/írást/végrehajtást jelez egy lapozható oldalon már van egy tipped arra, hogy miért esett le. Húzd át ezt a tippet ln
a 4. paraméterben a kívánt függvény eléréséhez.
ért Mi az IRQL? és az, hogy ez hogyan illeszkedik a kernel végrehajtásába, segít elkülöníteni a zajt a jelektől. Ha felhasználó vagy, akkor a következőkre koncentrálj: illesztőprogramok és hardverek (alapértelmezés szerint Verifierrel, eseményekkel és tesztekkel). Fejlesztéskor szigorúan tartsd be az IRQL, a nem lapozható memória és a spin lockokkal való szinkronizáció szabályait. A megfelelő eszközökkel (WinDbg, Verifier) és a paraméterek (1, 3 és 4) gondos leolvasásával... Ezek a hibaellenőrzések már nem rejtélyek és olyan problémákká válnak, amelyek módszeresen kezelhetők.
Szenvedélyes író a bájtok és általában a technológia világáról. Szeretem megosztani tudásomat írásban, és ezt fogom tenni ebben a blogban, megmutatom a legérdekesebb dolgokat a kütyükről, szoftverekről, hardverekről, technológiai trendekről stb. Célom, hogy egyszerű és szórakoztató módon segítsek eligazodni a digitális világban.