Delen via


Foutopsporingsberichten lezen en filteren

De routines DbgPrintEx, vDbgPrintExWithPrefix en KdPrintEx verzenden een bericht naar het kernelfoutopsporingsprogramma onder voorwaarden die u opgeeft. Met deze procedure kunt u berichten met lage prioriteit filteren.

Notitie

In Microsoft Windows Server 2003 en eerdere versies van Windows, zenden de routines DbgPrint en KdPrint berichten onvoorwaardelijk naar de kernel debugger. In Windows Vista en latere versies van Windows verzenden deze routines berichten voorwaardelijk, zoals DbgPrintEx en KdPrintEx. Welke versie van Windows u ook gebruikt, moet u DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix en KdPrintEx gebruiken, omdat u met deze routines de voorwaarden kunt beheren waaronder het bericht wordt verzonden.

Het filteren van foutopsporingsberichten

  1. Voor elk bericht dat u naar het foutopsporingsprogramma wilt verzenden, gebruikt u DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix of KdPrintEx in de code van uw stuurprogramma. Geef de juiste onderdeelnaam door aan de parameter ComponentId en geef een waarde door aan de parameter Niveau die de ernst of aard van dit bericht weerspiegelt. Het bericht zelf wordt doorgegeven aan de parameters Opmaak en argumenten met behulp van dezelfde syntaxis als printf.

  2. Stel de waarde van het juiste filtermasker voor onderdelen in. Elk onderdeel heeft een ander masker. De maskerwaarde geeft aan welke berichten van dat onderdeel worden weergegeven. U kunt het filtermasker voor onderdelen in het register instellen met behulp van een registereditor of in het geheugen met behulp van een kernelfoutopsporingsprogramma.

  3. Voeg een kernelfoutopsporingsprogramma toe aan de computer. Telkens wanneer uw stuurprogramma een bericht doorgeeft aan DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix of KdPrintEx, worden de waarden die worden doorgegeven aan ComponentId en Level vergeleken met de waarde van het bijbehorende filtermasker voor onderdelen. Als deze waarden voldoen aan bepaalde criteria, wordt het bericht verzonden naar het kernelfoutopsporingsprogramma en weergegeven. Anders wordt er geen bericht verzonden.

Notitie

Alle verwijzingen op deze pagina op DbgPrintEx zijn evenzeer van toepassing op KdPrintEx, vDbgPrintEx en vDbgPrintExWithPrefix.

De onderdeelnaam identificeren

Elk onderdeel heeft een afzonderlijk filtermasker. Hierdoor kan het foutopsporingsprogramma het filter voor elk onderdeel afzonderlijk configureren.

Elk onderdeel wordt op verschillende manieren aangeduid, afhankelijk van de context. In de parameter ComponentId van DbgPrintEx wordt de onderdeelnaam voorafgegaan door 'DPFLTR_' en achtervoegsel met '_ID'. In het register heeft het filtermasker van het onderdeel dezelfde naam als het onderdeel zelf. In het foutopsporingsprogramma wordt het filtermasker van het onderdeel voorafgegaan door 'Kd_' en gevolgd door '_Mask'.

Er is een volledige lijst met alle onderdeelnamen (in DPFLTR_XXXX_ID-indeling) in de Microsoft Windows Driver Kit (WDK) header dpfilter.h. De meeste van deze onderdeelnamen zijn gereserveerd voor Windows en voor stuurprogramma's die zijn geschreven door Microsoft.

Er zijn zes onderdeelnamen gereserveerd voor onafhankelijke hardwareleveranciers. Gebruik een van de volgende onderdeelnamen om te voorkomen dat de uitvoer van uw stuurprogramma wordt gecombineerd met de uitvoer van Windows-onderdelen:

Onderdeelnaam Stuurprogramma type
IHVVIDEO Videostuurprogramma
IHVAUDIO Audiostuurprogramma
IHVNETWORK Netwerkstuurprogramma
IHVSTREAMING Kernel Streaming-stuurprogramma
IHVBUS Buschauffeur
IHVDRIVER Elk ander type stuurprogramma

Als u bijvoorbeeld een videostuurprogramma schrijft, gebruikt u DPFLTR_IHVVIDEO_ID als de parameter ComponentId van DbgPrintEx, gebruikt u de waardenaam IHVVIDEO in het register en raadpleegt u Kd_IHVVIDEO_Mask in het foutopsporingsprogramma.

Alle berichten die door DbgPrint en KdPrint worden verzonden, zijn gekoppeld aan het onderdeel DEFAULT .

Het juiste niveau kiezen

De niveauparameter van de Routine DbgPrintEx is van het type DWORD. Het wordt gebruikt om het importantie-bitveld te bepalen. De verbinding tussen de parameter Niveau en dit bitveld is afhankelijk van de grootte van Niveau:

  • Als niveau gelijk is aan een getal tussen 0 en 31, inclusief, wordt het geïnterpreteerd als een bit shift. Het belangrijkheidsbitveld wordt ingesteld op de waarde 1 <<Niveau. Het kiezen van een waarde tussen 0 en 31 voor Niveau resulteert dus in een bitveld met precies één bitsset. Als niveau 0 is, is het bitveld gelijk aan 0x00000001; als niveau 31 is, is het bitveld gelijk aan 0x80000000.

  • Als niveau een getal is tussen 32 en 0xFFFFFFFF inclusief, wordt het waarde-bitveld ingesteld op de waarde van Niveau zelf.

Als u het bitveld dus wilt instellen op 0x00004000, kunt u Niveau opgeven als 0x00004000 of gewoon als 14. Bepaalde bitveldwaarden zijn niet mogelijk door dit systeem, inclusief een bitveld dat volledig nul is.

De volgende constanten kunnen handig zijn voor het instellen van de waarde van Niveau. Ze worden gedefinieerd in de Microsoft Windows Driver Kit (WDK) header dpfilter.h en de Windows SDK header ntrtl.h:

#define   DPFLTR_ERROR_LEVEL     0
#define   DPFLTR_WARNING_LEVEL   1
#define   DPFLTR_TRACE_LEVEL     2
#define   DPFLTR_INFO_LEVEL      3
#define   DPFLTR_MASK   0x80000000

Een eenvoudige manier om de parameter Niveau te gebruiken, is om altijd waarden tussen 0 en 31 te gebruiken, met behulp van de bits 0, 1, 2, 3 met de betekenis die wordt gegeven door DPFLTR_XXXX_LEVEL en het gebruik van de andere bits om te betekenen wat u kiest.

Een andere eenvoudige manier om de parameter Niveau te gebruiken, is door altijd expliciete bitvelden te gebruiken. Als u deze methode kiest, kunt u overwegen de waarde DPFLTR_MASK met uw bitveld te combineren; dit garandeert dat u niet per ongeluk een waarde gebruikt die kleiner is dan 32.

Als u wilt dat uw stuurprogramma compatibel is met de manier waarop Windows berichtniveaus gebruikt, moet u alleen de laagste bit (0x1) van het urgentie-bitveld instellen als er een ernstige fout optreedt. Als u waarden op niveau lager dan 32 gebruikt, komt dit overeen met DPFLTR_ERROR_LEVEL. Als deze bit is ingesteld, wordt uw bericht weergegeven wanneer iemand een kernelfoutopsporingsprogramma koppelt aan een computer waarop het stuurprogramma wordt uitgevoerd.

De waarschuwings-, tracerings- en informatieniveaus moeten in de juiste situaties worden gebruikt. Andere bits kunnen vrij worden gebruikt voor alle doeleinden die u nuttig vindt. Hierdoor kunt u een groot aantal berichttypen hebben die selectief kunnen worden weergegeven of verborgen.

Alle berichten die door DbgPrint en KdPrint worden verzonden, gedragen zich als DbgPrintEx en KdPrintEx berichten met Level gelijk aan DPFLTR_INFO_LEVEL. Met andere woorden, deze berichten hebben het derde bit van hun belangrijkheidbitveld ingesteld.

Het filtermasker voor onderdelen instellen

Er zijn twee manieren om een onderdeelfiltermasker in te stellen:

  • Het filtermasker van het onderdeel kan worden geopend in de registersleutel HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter. Maak of open deze sleutel met behulp van een register-editor. Maak onder deze sleutel een waarde met de naam van het gewenste onderdeel, in hoofdletters. Stel deze in op de DWORD-waarde die u wilt gebruiken als het filtermasker voor onderdelen.

  • Indien een kernel debugger actief is, kan het toegang krijgen tot de waarde voor het filtermasker van het onderdeel door het adres te derefereren dat is opgeslagen in het symbool Kd_XXXX_Mask, waarbij XXXX de gewenste onderdeelnaam is. U kunt de waarde van dit masker weergeven in WinDbg of KD met de opdracht dd (Display DWORD) of een nieuw onderdeelfiltermasker invoeren met de opdracht ed (Enter DWORD). Als er een risico is op dubbelzinnigheid van een symbool, kunt u dit symbool opgeven als nt!Kd_XXXX_Mask.

Filtermaskers die in het register zijn opgeslagen, worden van kracht tijdens het opstarten. Filtermaskers die door het foutopsporingsprogramma zijn gemaakt, worden onmiddellijk van kracht en blijven behouden totdat Windows opnieuw wordt opgestart. Een waarde die in het register is ingesteld, kan worden overschreven door het foutopsporingsprogramma, maar het filtermasker voor onderdelen retourneert de waarde die is opgegeven in het register als het systeem opnieuw wordt opgestart.

Er is ook een systeembreed masker genaamd WIN2000. Dit is standaard gelijk aan 0x1, hoewel het kan worden gewijzigd via het register of het foutopsporingsprogramma zoals alle andere onderdelen. Wanneer filteren wordt uitgevoerd, wordt elk onderdeelfiltermasker eerst ORed met het WIN2000 masker. Dit betekent met name dat onderdelen waarvan de maskers nooit zijn opgegeven, standaard op 0x1 worden gezet.

Criteria voor het weergeven van het bericht

Wanneer DbgPrintEx wordt aangeroepen in kernelmoduscode, vergelijkt Windows het bitveld voor berichtbelang dat is opgegeven door Niveau met het filtermasker van het onderdeel dat is opgegeven door ComponentId.

Notitie

Denk eraan dat wanneer de parameter Niveau tussen 0 en 31 ligt, het urgentie-bitveld gelijk is aan 1 <<niveau. Maar wanneer de parameter Niveau 32 of hoger is, is het belangrijkheidsbitveld simpelweg gelijk aan Niveau.

Windows voert een AND-bewerking uit op het belangrijkheidsbitveld en het componentenfiltermasker. Als het resultaat niet nul is, wordt het bericht verzonden naar het foutopsporingsprogramma.

Voorbeeld van foutopsporingsfilter

Stel dat u vóór de laatste opstart de volgende waarden hebt gemaakt in de Debug Print Filter-sleutel:

  • IHVVIDEO, met een waarde die gelijk is aan DWORD-0x2

  • IHVBUS, gelijk aan DWORD-0x7FF

Nu geeft u de volgende opdrachten uit in het kernelfoutopsporingsprogramma:

kd> ed Kd_IHVVIDEO_Mask 0x8 
kd> ed Kd_IHVAUDIO_Mask 0x7 

Op dit moment heeft het onderdeel IHVVIDEO een filtermasker van 0x8, heeft het onderdeel IHVAUDIO een filtermasker van 0x7 en heeft het onderdeel IHVBUS een filtermasker van 0x7FF.

Omdat deze maskers echter automatisch ORed zijn met het WIN2000 systeembrede masker (dat meestal gelijk is aan 0x1), is het IHVVIDEO-masker effectief gelijk aan 0x9. Onderdelen waarvan filtermaskers helemaal niet zijn ingesteld (bijvoorbeeld IHVSTREAMING of DEFAULT), hebben inderdaad een filtermasker van 0x1.

Stel nu dat de volgende functie-aanroepen plaatsvinden in verschillende stuurprogramma's:

DbgPrintEx( DPFLTR_IHVVIDEO_ID,  DPFLTR_INFO_LEVEL,   "First message.\n");
DbgPrintEx( DPFLTR_IHVAUDIO_ID,  7,                   "Second message.\n");
DbgPrintEx( DPFLTR_IHVBUS_ID,    DPFLTR_MASK | 0x10,  "Third message.\n");
DbgPrint( "Fourth message.\n");

Het eerste bericht heeft de niveauparameter gelijk aan DPFLTR_INFO_LEVEL, wat 3 is. Omdat dit minder dan 32 is, wordt het beschouwd als een bitverschuiving, wat resulteert in een belangrijke bitveld van 0x8. Deze waarde wordt vervolgens in een AND-bewerking uitgevoerd met het effectieve filtermasker van het IHVVIDEO-onderdeel van 0x9, wat een niet-nulresultaat oplevert. Het eerste bericht wordt dus verzonden naar het foutopsporingsprogramma.

Het tweede bericht heeft de parameter Niveau gelijk aan 7. Opnieuw wordt dit behandeld als een bitverschuiving, wat resulteert in een significant bitveld van 0x80. Dit wordt vervolgens ANDed met het filtermasker van het IHVAUDIO-onderdeel van 0x7, waardoor het resultaat nul is. Het tweede bericht wordt dus niet verzonden.

Het derde bericht heeft de niveauparameter gelijk aan DPFLTR_MASK | 0x10. Dit is groter dan 31, en daarom wordt het belangrijkheidsbitveld gelijkgesteld aan de waarde van Level -- met andere woorden, op 0x80000010. Dit wordt vervolgens bewerkt met een AND-bewerking met het filtermasker van het IHVBUS-onderdeel van 0x7FF, wat een niet-nul resultaat geeft. Het derde bericht wordt dus verzonden naar het foutopsporingsprogramma.

Het vierde bericht is doorgegeven aan DbgPrint in plaats van DbgPrintEx. In Windows Server 2003 en eerdere versies van Windows worden berichten die aan deze routine worden doorgegeven, altijd verzonden. In Windows Vista en latere versies van Windows krijgen berichten die aan deze routine worden doorgegeven altijd een standaardfilter. Het waarde-bitveld is gelijk aan 1 << DPFLTR_INFO_LEVEL, wat 0x00000008 is. Het onderdeel voor deze routine is STANDAARD. Omdat u het filtermasker STANDAARDonderdeel niet hebt ingesteld, heeft het een waarde van 0x1. Wanneer dit wordt onderworpen aan een AND-bewerking met het belangrijkheid-bitveld, is het resultaat nul. Het vierde bericht wordt dus niet verzonden.

DbgPrint-buffer en het foutopsporingsprogramma

Wanneer de DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint of KdPrintEx routine een bericht naar de debugger verzendt, wordt de opgemaakte tekenreeks verzonden naar de DbgPrint buffer. De inhoud van deze buffer wordt direct weergegeven in het opdrachtvenster Foutopsporingsprogramma, tenzij u deze weergave hebt uitgeschakeld met behulp van de optie Uitvoer van Buffer DbgPrint van GFlags.

Tijdens lokale kernelfoutopsporing en elke andere keer dat deze weergave is uitgeschakeld, kan de inhoud van de DbgPrint-buffer alleen worden bekeken met de !dbgprint extensieopdracht.

Elke enkele aanroep naar DbgPrint, DbgPrintEx, vDbgPrintEx, vDbgPrintExWithPrefix, KdPrint of KdPrintEx verzendt slechts 512 bytes aan informatie. Uitvoer die langer is dan de 512 bytes, gaat verloren. De DbgPrint-buffer zelf kan maximaal 4 kB aan gegevens bevatten op een gratis build van Windows en maximaal 32 kB aan gegevens in een gecontroleerd build van Windows. In Windows Server 2003 en nieuwere versies van Windows kunt u het hulpprogramma KDbgCtrl gebruiken om de grootte van de DbgPrint-buffer te wijzigen. Dit hulpprogramma maakt deel uit van Hulpprogramma's voor foutopsporing voor Windows.

Notitie

Gecontroleerde builds waren beschikbaar in oudere versies van Windows, vóór Windows 10 versie 1803. Gebruik hulpprogramma's zoals Driver Verifier en GFlags om de stuurprogrammacode in latere versies van Windows te controleren.

Als een bericht wordt gefilterd vanwege de waarden voor ComponentId en Niveau , wordt het niet verzonden via de foutopsporingsverbinding. Daarom is er geen manier om dit bericht weer te geven in het foutopsporingsprogramma.