- IRQL përcakton prioritetet e ekzekutimit dhe maskon ndërprerjet sipas nivelit, mbi DISPATCH ai komandon IRQL-në, jo prioritetin e thread-it.
- L BSOD 0xA/0xD1 zakonisht shkaktohen nga qasjet në memorien e faqosshme ose të pavlefshme në IRQL të lartë dhe adresa ose kod të faqosshëm të pasaktë.
- WinDbg dhe Driver Verifier janë çelësi: përdorni !analyze, !irql, ln, .trap, !pool, !address dhe shqyrtoni parametrat 1, 3 dhe 4.
- En Shoferët, parandalon gabimet e faqes në IRQL të lartë, përdor memorie jo të faqosur dhe bllokime rrotullimi; për përdoruesin, përditëson/izolon drajverët problematikë.
Nëse keni parë ndonjëherë një ekran blu me mesazhe si IRQL_NOT_LESS_OR_EQUAL o DRIVER_IRQL_NOT_LESS_OR_EQUAL, ndoshta keni hasur në një koncept që është pak i njohur jashtë botës së drajverëve: IRQL (Niveli i Kërkesës për Ndërprerje). Në Dritaret, ky nivel i përparësisë së ndërprerjes ka përparësi mbi përparësinë e fijeve kur sistemi është mbi një prag të caktuar, dhe kjo ka pasoja të drejtpërdrejta në stabilitet.
Në rreshtat e ardhshëm do të gjeni një udhëzues i plotë dhe në spanjisht nga Spanja rreth asaj që është IRQL, si funksionon ajo, pse shkakton ekrane blu, si ta diagnostikoni problemin me WinDbg dhe çfarë të bëni pavarësisht nëse jeni përdorues që po përjetoni gabimin ose po zhvilloni drajverë në modalitetin kernel. Le të fillojmë punën.
Çfarë është IRQL (Niveli i Kërkesës për Ndërprerje) në Windows?
Në Windows, IRQL përcakton përparësinë e hardware në të cilën funksionon një procesor në çdo kohë të caktuar. Brenda Modelit të Drajverit të Windows (WDM), kodi që ekzekutohet me një IRQL të ulët mund të ndërpritet nga kodi që ekzekutohet me një IRQL më të lartë. Në fakt, në një kompjuter të vetëm me shumë bërthama, çdo CPU mund të jetë në një IRQL të ndryshme, gjë që e ndërlikon sinkronizimin.
Ekziston një rregull kryesor: Kur një CPU po funksionon në një IRQL mbi PASSIVE_LEVEL, ajo mund të parandalohet vetëm nga aktiviteti në një IRQL edhe më të lartë.Kjo organizon bashkëjetesën midis kodit të përdoruesit, funksioneve të bërthamës, thirrësve të shtyrë (DPC) dhe rutinave të shërbimit të ndërprerjes së pajisjes (ISR).
Nivelet dhe prioritetet: PASSIVE_LEVEL, APC_LEVEL, DISPATCH_LEVEL dhe DIRQL
Në terma të përgjithshëm, Në x86, përdoren vlerat IRQL midis 0 dhe 31; në x64, midis 0 dhe 15Kuptimi praktik është i njëjtë: IRQL 0 (PASSIVE_LEVEL) është vendi ku ekzekutohet kodi normal i përdoruesit dhe shumë funksione të drajverit; Gabimet e APC dhe faqes Ato zakonisht hartëzohen në IRQL 1 (APC_LEVEL); IRQL 2 (DISPATCH_LEVEL) përfshin planifikuesin e fijeve dhe DPC-të. Mbi DISPATCH_LEVEL janë nivelet e rezervuara për ndërprerjet e pajisjes (të njohura si DIRQL) dhe përdorime të tjera të brendshme si HIGH_LEVEL.
Në ekosistemin e shoferit, Shumë rutina të zakonshme funksionojnë në DISPATCH_LEVELPër shembull, DPC dhe StartIo. Ky dizajn siguron që, ndërsa njëri prej tyre prek radhët e brendshme ose burimet e tjera të përbashkëta, një rutinë tjetër në të njëjtin nivel nuk e parapërgatit atë në atë CPU, sepse rregulli i parapërgatitjes lejon vetëm ndërprerje në nivele më të larta.
Midis DISPATCH_LEVEL dhe niveleve të profilizimit/lartë ka vend për ndërprerjet e harduerit të secilës pajisje (DIRQL)IRQL e një pajisjeje përcakton përparësinë e saj ndaj pajisjeve të tjera. Një drajver WDM e merr këtë IRQL gjatë IRP_MJ_PNP me IRP_MN_START_DEVICE. Kjo IRQL e pajisjes nuk është një vlerë fikse globale, por më tepër vlera e shoqëruar me një linjë specifike ndërprerjeje.
IRQL kundrejt Prioritetit të Fijeve
Këshillohet që të mos ngatërroni konceptet: Prioriteti i fijes përcakton kur planifikuesi paraprin dhe cili fije ekzekutohet.; IRQL kontrollon se çfarë lloj aktiviteti mund të ekzekutohet dhe cilat ndërprerje maskohen. Mbi DISPATCH_LEVEL, nuk ka ndërrim të fijeve: është IRQL që kontrollon, jo përparësia e fijeve.
IRQL dhe Paging: Çfarë nuk duhet të bëni
Një efekt i menjëhershëm i rritjes së IRQL është se sistemi nuk mund të trajtojë gabimet e faqesRregulli i artë: kodi që ekzekutohet në DISPATCH_LEVEL ose më lart nuk mund të shkaktojë gabime në faqe. Në praktikë, kjo do të thotë që ato rutina dhe të dhënat që prekin duhet të qëndrojë në memorien jo të faqosurPërveç kësaj, disa ndihmës të kernelit e kufizojnë përdorimin e tyre bazuar në IRQL: për shembull, KeWaitForSingleObject
DISPATCH_LEVEL mund të thirret vetëm nëse nuk po bllokoni (kohëzgjatje zero), dhe për kohëzgjatje jo-zero, duhet të jeni nën DISPATCH_LEVEL.
Kontroll implicit dhe i qartë i IRQL-së
Shumicën e kohës, Vetë sistemi i thërret rutinat tuaja në IRQL-në e saktë për atë që duhet të bëjnë. Rutinat e dërgimit për IRP-të funksionojnë në PASSIVE_LEVEL (ato mund të bllokojnë ose të thërrasin çdo ndihmës), StartIo dhe DPC funksionojnë në DISPATCH_LEVEL për të mbrojtur radhët e përbashkëta, dhe ISR-të funksionojnë në DIRQL.
Nëse keni nevojë ta kontrolloni atë në mënyrë të qartë, Ju mund ta rrisni dhe ulni IRQL-në me KeRaiseIrql
y KeLowerIrql
Ekziston një shkurtore shumë e përdorur: KeRaiseIrqlToDpcLevel()
kthen IRQL-në e mëparshme dhe ju lë në DISPATCH_LEVEL. E rëndësishme: Mos e ulni kurrë IRQL-në nën vlerën që ishte kur sistemi ju thirri; ndërprerja e këtij sinkronizimi mund të hapë dritare shumë serioze gare.
Gabimet e ekranit blu që lidhen me IRQL: IRQL_NOT_LESS_OR_EQUAL dhe DRIVER_IRQL_NOT_LESS_OR_EQUAL
Dy kontrolle klasike të gabimeve që lidhen me këto probleme janë IRQL_NOT_LESS_OR_EQUAL (0xA) y DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1)Të dyja tregojnë një përpjekje për të aksesuar një adresë të faqueshme (ose të pavlefshme) në një IRQL që është shumë e lartë. Kjo zakonisht ndodh për shkak të drajverëve që përdorin adresa të pasakta, çreferencimit të treguesve të këqij ose ekzekutimit të kodit të faqueshëm në nivele të papërshtatshme.
Në rastin specifik të DRIVER_IRQL_NOT_LESS_OR_EQUAL (0x000000D1), parametrat janë shumë informues: 1) adresa e kujtesës së referuar; 2) IRQL në atë kohë; 3) lloji i aksesit (0 lexim, 1 shkrim, 2/8 ekzekutim); 4) adresa e instruksionit që i referoi kujtesës. Me debugger-in mund të përdorni ln
në parametrin 4 për rendit simbolin më të afërt dhe di se cili funksion po ekzekutohej.
Shkaqe të zakonshme për t'u mbajtur mend
Përtej kodit specifik, ka modele që përsëriten. Çreferencimi i një treguesi të pavlefshëm në DISPATCH_LEVEL ose më të lartë Kjo është një recetë e sigurt për katastrofë. Qasja në të dhënat e faqëzueshme në atë nivel, ose ekzekutimi i kodit të faqëzueshëm (p.sh., një funksion i shënuar si i faqëzueshëm), gjithashtu aktivizon kontrollin e gabimeve.
Raste të tjera të zakonshme përfshijnë thirrni një funksion në një drajver tjetër që është shkarkuar tashmë (tregues funksioni i varur), ose thirret në mënyrë indirekte nëpërmjet një treguesi funksioni të pavlefshëm. Shpesh, nëse sistemi është në gjendje të identifikojë një modul, do ta shihni emrin e tij në vetë ekranin blu, dhe ai ruhet gjithashtu në KiBugCheckDriver
, i arritshëm me dx KiBugCheckDriver
nga WinDbg.
Një detaj praktik: Në shumicën e D1/A, problemi i vërtetë nuk është vetë IRQL., por më tepër adresa e kujtesës së referuar. Kjo është arsyeja pse parametrat 1, 3 dhe 4 janë thelbësorë për fokusimin e diagnozës.
Diagnostika me WinDbg: Komanda të dobishme dhe lexim parametrash
Për të punuar në këto raste, WinDbg është mjeti kryesor, dhe nëse BSOD përmend ntoskrnl.exe Ky informacion ofron shumë udhëzime nëse defekti është në nënsistemin e kernelit. Filloni nga !analyze -v
për të marrë një përmbledhje të kontrollit të gabimeve, pirgut dhe, nëse jeni me fat, modulit të përfshirë. Nëse dokumenti përfshin një kornizë kapjeje, .trap
ju vendos në kontekstin e një CPU-je të dështuar.
L komandat e grumbullit si k
, kb
, kc
, kd
, kp
, kP
, kv
Ato ju tregojnë nivele të ndryshme të detajeve të gjurmës së prapme. Me ln
në parametrin 4 mund të kaloni te instruksioni që i referohej memories dhe merrni simbolin e afërt. Dhe nëse dyshoni se niveli i përparësisë funksionon para ndërprerjes, !irql
ju tregon IRQL-në e ruajtur për procesorin e synuar (p.sh. DISPATCH_LEVEL).
Për të analizuar drejtimin e parametrit 1, !pool
Do t'ju tregojë nëse i përket një grupi të faqosur; !address
y !pte
thellohuni në hartëzimin e kujtesës së asaj zone. Mund të përdorni komandat e shfaqjes së memories për të inspektuar përmbajtjen që u përpoq të aksesohej. Së fundmi, u
, ub
, uu
ju lejojnë të çmontoni rreth adresës së parametrit 4.
Mos harroni lm t n
për të listuar modulet e ngarkuara y !memusage
për gjendjen e përgjithshme të kujtesës. Nëse KiBugCheckDriver
ka diçka, dx KiBugCheckDriver
Do të kthejë emrin e modulit Unicode: në një shembull tipik, "Wdf01000.sys" u pa si drajveri i përfshirë gjatë kontrollit të gabimeve.
Mjetet e Sistemit: Verifikuesi i Drajverit, Shikuesi i Ngjarjeve dhe Diagnostika
El Verifikuesi i Shoferit Shqyrton sjelljen e drajverëve në kohë reale dhe detyron gabime kur zbulon përdorim të gabuar të burimeve (siç është grupi), duke ngritur një përjashtim për të izoluar zonën problematike të kodit. Ai niset me verifier
nga komandë e shpejtë dhe këshillohet të zgjidhni grupin më të vogël të mundshëm të drajverëve për të shmangur shtimin e shumë kostove.
Nëse nuk e shihni veten me WinDbg, zbatoni masa themeloreKontrolloni regjistrin e sistemit në Event Viewer për gabime që tregojnë një pajisje/drejtues specifik; përditësoni ose çaktivizoni drejtuesin e cituar nga ekrani blu; verifikoni përputhshmërinë e harduerit me versionin tuaj të Windows; dhe përdorni Windows Memory Diagnostic nëse dyshoni për RAM. Këto veprime, megjithëse të thjeshta, ata zgjidhin një numër të madh rastesh.
Raste nga jeta reale: Kur BSOD-të duken të rastësishme
Një përdorues me Windows 10 Pro (CPU AMD Ryzen 5 3400G, GPU NVIDIA Pllaka GeForce GTX 1660 Ti dhe Gigabyte B450 AORUS PRO WIFI, 16 GB RAM) po përjetonte ekrane "IRQL_LESS_OR_NOT_EQUAL" me ndërprerje. Unë kisha përditësuar tashmë drajverët thelbësorë (rrjetin, grafikën), kisha instaluar të gjitha përditësimet e Windows dhe kisha ekzekutuar mjetin e memories, të gjitha këto pa zbuluar ndonjë problem.
Në skenarë të tillë, Hapi tjetër është analizimi i dump-eve me WinDbg dhe kërkoni modele: procese të përfshira kur bie (për shembull, explorer.exe
), module të ndërfaqes grafike (win32kfull.sys
) dhe funksione të tilla si xxxProcessNotifyWinEvent
që shfaqet në stack. Edhe pse ky modul është Windows, shkaktari është shpesh një drajver i palës së tretë (grafikë, hyrje, mbivendosje, karta kapjeje) që përdor memorien në një IRQL të papërshtatshme dhe defekti lind brenda win32k
.
Rekomandimi praktik këtu është çaktivizo përkohësisht softuerin e mbivendosjes (kapja, GPU OSD), drajverët agresivë periferikë të softuerëve (maus/tastiera me makro) dhe versionet beta të drajverëve grafikë, dhe ta ngushtoni atë. Përdorimi i Verifikuesit të Drajverit te të dyshuarit mund të ndihmojë në ngushtimin e problemit me një grumbull më të qartë.
Një model shumë i zakonshëm rrjeti: ndis.sys nuk është gjithmonë fajtori
Një rast tjetër tipik: pamje e ekranit me ndis.sys (shtresa e rrjetit Windows). Në një kompjuter të vërtetë, sistemi do të rrëzohej menjëherë pas nisjes. Zgjidhja praktike ishte të nisej në Modaliteti i sigurt pa funksionet e rrjetit, hapni Menaxheri i pajisjes dhe çaktivizoni adaptorët te "Adaptorët e Rrjetit" për të izoluar problemin.
Në atë ekip kishte një Kontrolluesi i familjes Realtek PCIe GBE dhe një Atheros AR5007GDuke i çaktivizuar të dyja, u zbulua se shkaku i vërtetë ishte athrx.sys
(Atheros), megjithëse ekrani blu i përmendur ndis.sys
Deponia e konfirmoi këtë: pirgu kaloi nëpër ndis!NdisFreeTimerObject
por moduli fajtor ishte athrx.sys
Korrigjimi përfundimtar ishte çinstaloni pajisjen dhe instaloni drejtuesit zyrtarë të azhurnuar Nga faqja e internetit e prodhuesit të Atheros. Morali: Moduli i cituar në BSOD mund të jetë pjesë e nënsistemit të prekur, jo burimi.
Përgjigje tipike e mbështetjes dhe hapa të shpejtë për përdoruesit
Në një shkëmbim të sinqertë mbështetjeje, një teknik u përgjigj: "Më vjen keq për shqetësimin. Mund të jetë një problem me drajverin, memorien ose antivirusin. Ju lutemi përditësoni drajverët tuaj dhe, nëse vazhdon, kryeni diagnostikimin e memories."Kjo është një këshillë bazë, por e vlefshme; megjithatë, nëse gabimet vazhdojnë, është një ide e mirë të vazhdohet më tej me Verifikuesin dhe analizën e dump-it.
Për përdoruesit jo-teknikë, një protokoll i arsyeshëm do të ishte: 1) Kontrolloni ngjarjet e sistemit, 2) Përditësoni drajverët kryesorë (çipset/rrjet/grafikë), 3) Kontrolloni RAM-in me mjetin e integruar, 4) test boot pastroni pa softuer të palëve të treta që fut grepa në kernel/GUI, dhe 5) përdorni Verifier në drajverët e palëve të treta nëse asgjë nuk është e qartë.
Praktikat më të mira për zhvilluesit e shoferëve
Nëse jeni duke zhvilluar dhe hasni rastësisht D1/A, kontrolloni që rutina e ekzekutimit nuk është shënuar si e faqosshme Mos i thirrni funksionet e faqëzueshme ndërsa ekzekutohen në DISPATCH_LEVEL ose më të lartë. Kjo përfshin shmangien e referencave ndaj të dhënave në seksionet e faqëzuara dhe respektimin e kufizimeve IRQL për ndihmësit e kernelit të përshkruara në DDK.
Për të sinkronizuar të dhënat e përbashkëta, zbato rregullin "gjithmonë qase të dhënat e përbashkëta me të njëjtën IRQL të lartë" dhe përdorni bllokime rrotulluese kur është e përshtatshme. Në multiprocesorë, vetëm IRQL nuk garanton përjashtim midis CPU-ve të ndryshme; bllokimet rrotulluese e rrisin IRQL-në (në DISPATCH_LEVEL) dhe koordinojnë aksesin midis bërthamave. Nëse keni nevojë të operoni në regjistra të ndjeshëm harduerësh, KeSynchronizeExecution
ju ndihmon të ekzekutoni seksionet kritike në DIRQL-në e saktë.
Kur plani kërkon rritjen e IRQL, SHBA KeRaiseIrqlToDpcLevel
për DISPATCH_LEVEL ose KeRaiseIrql
me kujdes, duke ruajtur IRQL-në e mëparshme dhe duke e rikthyer atë saktësisht me KeLowerIrql
Shko poshtë IRQL-së hyrëse, qoftë edhe vetëm për një çast, Është një gabim serioz sinkronizimi.
Marrëdhënia me ndërprerjet dhe harduerin
IRQL është mekanizmi me anë të të cilit Windows Urdhrat ndërpresin prioritetet dhe detyra të caktuara të brendshmeNë nivelin arkitektonik, lidhet me koncepte të tilla si "Ndërprerje", "Trajnues i ndërprerjeve" ose "Niveli i përparësisë së ndërprerjeve" dhe, në platformat klasike, me Kontrolluesi i ndërprerjes i programueshëm (PIC)Në sisteme të tjera, kontrolli i përparësive shprehet nëpërmjet mekanizmave të tillë si spl en Unix; ideja e përgjithshme është e njëjtë: kush mund të ndërpresë kë.
Këshilla të Avancuara për Debugging
Në deponitë ku pirgu tregon win32kfull!xxxProcessNotifyWinEvent
me kontrollin e gabimeve 0xA/0xD1, inspektoni kontekstin me .process
y .thread
(nëse është e mundur), shikoni procese si explorer.exe
en !process 0 1
dhe kontrolloni mbivendosjet dhe drajverët e ndërveprimit GUI. Shumë herë problemi Është kujtesa e korruptuar nga një palë e tretë që shfaqet në atë rrugë.
Mos harroni të kontrolloni IRQL-në me !irql
, dhe kontrasti: nëse jeni në DISPATCH_LEVEL (2) dhe parametri 3 tregon lexim/shkrim/ekzekutim në një faqe të faqosueshme, ju tashmë keni një ide se pse ka rënë. Kryqëzoni këtë ide me ln
në parametrin 4 për të marrë funksionin specifik.
kuptoj Çfarë është IRQL? dhe mënyra se si përshtatet në ekzekutimin e kernelit ndihmon në ndarjen e zhurmës nga sinjalet. Nëse jeni përdorues, përqendrohuni te drajverët dhe pajisjet (me Verifikues, ngjarje dhe teste si parazgjedhje). Nëse zhvilloni, ndiqni me përpikëri rregullat për IRQL, memorien pa faqe dhe sinkronizimin me brava rrotulluese. Me mjetet e duhura (WinDbg, Verifikues) dhe leximin e kujdesshëm të parametrave (1, 3 dhe 4), Këto kontrolle të gabimeve nuk janë më një mister dhe ato bëhen probleme që mund të adresohen në mënyrë metodike.
Shkrimtar i apasionuar pas botës së bajteve dhe teknologjisë në përgjithësi. Më pëlqen të ndaj njohuritë e mia përmes shkrimit, dhe kjo është ajo që do të bëj në këtë blog, duke ju treguar të gjitha gjërat më interesante në lidhje me pajisjet, softuerin, harduerin, tendencat teknologjike dhe më shumë. Qëllimi im është t'ju ndihmoj të lundroni në botën dixhitale në një mënyrë të thjeshtë dhe argëtuese.