Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här laboratoriet innehåller praktiska övningar som visar hur du felsöker drivrutinen för Sysvad-ljudkärnans drivrutin i kernel-läge.
Microsoft Windows Debugger (WinDbg) är ett kraftfullt Windows-baserat felsökningsverktyg som du kan använda för att utföra felsökning i användarläge och kernelläge. WinDbg tillhandahåller felsökning på källnivå för Windows-kerneln, drivrutiner i kernelläge och systemtjänster samt program och drivrutiner i användarläge.
WinDbg kan gå igenom källkod, ange brytpunkter, visa variabler (inklusive C++-objekt), stackspårningar och minne. Med dess kommandofönster för felsökning kan användaren utfärda en mängd olika kommandon.
Labbkonfiguration
Du behöver följande maskinvara för att kunna slutföra labbet:
- En bärbar dator eller stationär dator (värd) som kör Windows 10
- En bärbar dator eller stationär dator (mål) som kör Windows 10
- En nätverkshubb/router och nätverkskablar för att ansluta de två datorerna
- Åtkomst till Internet för att ladda ned symbolfiler
Du behöver följande programvara för att kunna slutföra labbet.
- Microsoft Visual Studio 2017
- Windows Software Development Kit (SDK) för Windows 10
- Windows Driver Kit (WDK) för Windows 10
- Sysvad-exempelljuddrivrutinen för Windows 10
Information om hur du laddar ned och installerar WDK finns i Ladda ned Windows Driver Kit (WDK).
Genomgång av Sysvad-felsökning
Det här laboratoriet leder dig genom processen att felsöka en drivrutin i kernelläge. Övningarna använder Syvad-virtuella ljuddrivrutinexempel. Eftersom Syvad-ljuddrivrutinen inte interagerar med den faktiska ljudmaskinvaran kan den användas på de flesta enheter. Labbet täcker följande uppgifter:
- Avsnitt 1: Anslut till en WinDbg-session i kernelläge
- Avsnitt 2: felsökningskommandon och tekniker i kernelläge
- Avsnitt 3: Ladda ned och skapa Sysvad-ljuddrivrutinen
- Avsnitt 4: Installera Sysvad-ljuddrivrutinen i målsystemet
- Avsnitt 5: Använd WinDbg för att visa information om drivrutinen
- Avsnitt 6: Visa information om plug and play-enhetens träd
- Avsnitt 7: Arbeta med brytpunkter och källkod
- Avsnitt 8: Titta på variabler
- Avsnitt 9: Visa anropsstackar
- Avsnitt 10: Visa processer och trådar
- Avsnitt 11: IRQL, register och demontering
- Avsnitt 12: Arbeta med minne
- Avsnitt 13: Avsluta WinDbg-sessionen
- Avsnitt 14: Windows-felsökningsresurser
Ekodrivrutinslabb
Echo-drivrutinen är en enklare drivrutin än Sysvad-ljuddrivrutinen. Om du inte har använt WinDbg tidigare kan du överväga att först slutföra felsökningen av universella drivrutiner – steg för steg-labb (Echo-kernelläge). Det här labbet återanvänder installationsanvisningarna från labbet, så om du har slutfört labbet kan du hoppa över avsnitt 1 och 2 här.
Avsnitt 1: Anslut till en WinDbg-session i kernelläge
I avsnitt 1 konfigurerar du nätverksfelsökning på värd- och målsystemet.
Datorerna i den här labbuppgiften måste konfigureras för att använda en Ethernet-nätverksanslutning för kernel-felsökning.
Det här labbet använder två datorer. WinDbg körs på värdsystemet och Sysvad-drivrutinen körs på målsystemet .
Använd en nätverkshubb/router och nätverkskablar för att ansluta de två datorerna.
Om du vill arbeta med program i kernelläge och använda WinDbg rekommenderar vi att du använder KDNET via Ethernet-transport. Information om hur du använder Ethernet-transportprotokollet finns i Komma igång med WinDbg (Kernel-Mode). Mer information om hur du konfigurerar måldatorn finns i Förbereda en dator för manuell drivrutinsdistribution och Konfigurera KDNET-nätverkskärnfelsökning automatiskt.
Konfigurera felsökning i kernelläge med ethernet
Utför följande steg för att aktivera felsökning i kernelläge i målsystemet.
<– På värdsystemet
- Öppna en kommandotolk i värdsystemet och skriv ipconfig /all för att fastställa dess IP-adress.
C:\>ipconfig /all
Windows IP Configuration
Host Name . . . . . . . . . . . . : TARGETPC
...
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b3
Autoconfiguration IPv4 Address. . : 169.182.1.1
Subnet Mask . . . . . . . . . . . : 255.255.0.0
Default Gateway . . . . . . . . . :
Registrera IP-adressen för värdsystemet: ______________________________________
Registrera värdsystemets värdnamn: ______________________________________
–> I målsystemet
- Öppna en kommandotolk i målsystemet och använd ping-kommandot för att bekräfta nätverksanslutningen mellan de två systemen. Använd den faktiska IP-adressen för värdsystemet som du registrerade i stället för 169.182.1.1 som visas i exempelutdata.
C:\> ping 169.182.1.1
Pinging 169.182.1.1 with 32 bytes of data:
Reply from 169.182.1.1: bytes=32 time=1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Ping statistics for 169.182.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 1ms, Average = 0ms
Utför följande steg för att använda KDNET-verktyget för att aktivera felsökning i kernelläge i målsystemet.
Leta reda på WDK KDNET-katalogen i värdsystemet. Som standard finns den här.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
Den här labben förutsätter att båda datorerna kör en 64-bitarsversion av Windows på både måldatorn och värddatorn. Om så inte är fallet är det bästa sättet att köra verktyg med samma bitstorlek på värddatorn som måldatorn använder. Till exempel, om målet kör 32-bitars Windows, ska du köra en 32-bitarsversion av felsökningsprogrammet på värddatorn. Mer information finns i Välja 32-bitars eller 64-bitars felsökningsverktyg.
Lokalisera dessa två filer och kopiera dem till en nätverksdelning eller en USB-enhet, så att de finns tillgängliga på måldatorn.
kdnet.exe
VerifiedNICList.xml
Öppna ett kommandotolksfönster som administratör på måldatorn. Ange det här kommandot för att verifiera att nätverkskortet på måldatorn stöds.
C:\KDNET>kdnet
Network debugging is supported on the following NICs:
busparams=0.25.0, Intel(R) 82579LM Gigabit Network Connection, KDNET is running on this NIC.kdnet.exe
- Ange värdsystemets IP-adress genom att ange det här kommandot. Använd den faktiska IP-adressen för värdsystemet som du registrerade i stället för 169.182.1.1 som visas i exempelutdata. Välj en unik portadress för varje mål-/värdpar som du arbetar med, till exempel 50010.
C:\>kdnet 169.182.1.1 50010
Enabling network debugging on Intel(R) 82577LM Gigabit Network Connection.
Key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
Viktigt!
Innan du använder BCDEdit för att ändra startinformationen kan du tillfälligt behöva pausa Windows-säkerhetsfunktioner som BitLocker och Säker start på testdatorn. Återaktivera dessa säkerhetsfunktioner när testningen är klar och hantera testdatorn på rätt sätt när säkerhetsfunktionerna är inaktiverade. Säker start inaktiveras vanligtvis i UEFI. Om du vill komma åt UEFI-inställningen använder du System, Recovery, Advanced start-up. Vid omstart väljer du Felsöka, Avancerade alternativ, UEFI-inställningar för inbyggd programvara. Var försiktig, eftersom fel inställning av UEFI-alternativ eller inaktivering av BitLocker kan göra systemet obrukbart.
- Skriv det här kommandot för att bekräfta att dbgsettings har angetts korrekt.
C:\> bcdedit /dbgsettings
busparams 0.25.0
key 2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
debugtype NET
hostip 169.182.1.1
port 50010
dhcp Yes
The operation completed successfully.
Kopiera den automatiskt genererade unika nyckeln till en textfil för att undvika att behöva skriva in den på värddatorn. Kopiera textfilen med nyckeln över till värdsystemet.
Obs!Brandväggar och felsökningsprogram
Om du får ett popup-meddelande från brandväggen och vill använda felsökningsprogrammet markerar du alla tre rutorna.
<– På värdsystemet
- Öppna kommandotolken som administratör på värddatorn. Byt till katalogen WinDbg.exe. Vi använder x64version av WinDbg.exe från Windows Driver Kit (WDK) som installerades som en del av Windows Kit-installationen.
C:\> Cd C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
- Starta WinDbg med fjärranvändarfelsökning med hjälp av följande kommando. Värdet för nyckeln och porten stämmer överens med det du angav tidigare med BCDEdit på måldatorn.
C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
->I målsystemet
Starta om målsystemet.
<-På värdsystemet
Om en minut eller två ska felsökningsutdata visas i värdsystemet.
Felsökningskommandofönstret är det primära informationsfönstret för felsökning i WinDbg. Du kan ange felsökningskommandon och visa kommandoutdata i det här fönstret.
Felsökningskommandofönstret är uppdelat i två fönsterrutor. Du skriver kommandon i det mindre fönstret (kommandoinmatningsfönstret) längst ned i fönstret och visar kommandoutdata i det större fönstret överst i fönstret.
I kommandoinmatningsfönstret använder du uppåtpilen och nedåtpilen för att bläddra igenom kommandohistoriken. När ett kommando visas kan du redigera det eller trycka på RETUR för att köra kommandot.
Avsnitt 2: felsökningskommandon och tekniker i kernelläge
I avsnitt 2 använder du felsökningskommandon för att visa information om målsystemet.
<– På värdsystemet
Aktivera DML (Debugger Markup Language) med .prefer_dml
Vissa felsökningskommandon visar text med hjälp av felsökningsprogrammets markupspråk som du kan välja för att snabbt samla in mer information.
- Använd Ctrl+Break (Rullningslås) i WinDBg för att bryta sig in i koden som körs i målsystemet. Det kan ta lite tid för målsystemet att svara.
- Skriv följande kommando för att aktivera DML i felsökningskommandofönstret.
0: kd> .prefer_dml 1
DML versions of commands on by default
Använd .hh för att få hjälp
Du kan komma åt referenskommandohjälpen med kommandot .hh .
- Skriv följande kommando för att visa kommandoreferenshjälpen för .prefer_dml.
0: kd> .hh .prefer_dml
Felsökningshjälpfilen visar hjälp för kommandot .prefer_dml .
Visa windowsversionen i målsystemet
- Visa detaljerad versionsinformation i målsystemet genom att skriva kommandot vertarget (Visa måldatorversion) i WinDbg-fönstret.
0: kd> vertarget
Windows 10 Kernel Version 9926 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 9926.0.amd64fre.fbl_awesome1501.150119-1648
Machine Name: ""
Kernel base = 0xfffff801`8d283000 PsLoadedModuleList = 0xfffff801`8d58aef0
Debug session time: Fri Feb 20 10:15:17.807 2015 (UTC - 8:00)
System Uptime: 0 days 01:31:58.931
Visa en lista över de inlästa modulerna
- Du kan kontrollera att du arbetar med rätt kernellägesprocess genom att visa de inlästa modulerna genom att skriva kommandot lm (List Loaded Modules) i WinDbg-fönstret.
0: Kd> lm
start end module name
fffff801`09200000 fffff801`0925f000 volmgrx (no symbols)
fffff801`09261000 fffff801`092de000 mcupdate_GenuineIntel (no symbols)
fffff801`092de000 fffff801`092ec000 werkernel (export symbols) werkernel.sys
fffff801`092ec000 fffff801`0934d000 CLFS (export symbols) CLFS.SYS
fffff801`0934d000 fffff801`0936f000 tm (export symbols) tm.sys
fffff801`0936f000 fffff801`09384000 PSHED (export symbols) PSHED.dll
fffff801`09384000 fffff801`0938e000 BOOTVID (export symbols) BOOTVID.dll
fffff801`0938e000 fffff801`093f7000 spaceport (no symbols)
fffff801`09400000 fffff801`094cf000 Wdf01000 (no symbols)
fffff801`094d9000 fffff801`09561000 CI (export symbols) CI.dll
...
Notera Utdata som har utelämnats anges med "… " i det här labbet.
Eftersom vi ännu inte har angett symbolsökvägen och inlästa symboler är begränsad information tillgänglig i felsökningsprogrammet.
Avsnitt 3: Ladda ned och skapa Sysvad-ljuddrivrutinen
I avsnitt 3 laddar du ned och skapar ljuddrivrutinen Sysvad.
Vanligtvis arbetar du med din egen drivrutinskod när du använder WinDbg. För att bekanta dig med felsökning av ljuddrivrutiner används den virtuella ljudexempeldrivrutinen Sysvad. Det här exemplet används för att illustrera hur du kan gå stegvis genom ursprunglig kod i kärnläge. Den här tekniken kan vara mycket värdefull för felsökning av komplexa kodproblem i kernelläge.
Utför följande steg för att ladda ned och skapa Sysvad-exempelljuddrivrutinen.
Ladda ned och extrahera Sysvad-ljudexemplet från GitHub
Du kan använda en webbläsare för att visa Sysvad-exemplet och Readme.md filen här:
https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad
Det här labbet visar hur du laddar ned de universella drivrutinsexemplen i en zip-fil.
a. Ladda ned filen master.zip till den lokala hårddisken.
https://github.com/Microsoft/Windows-driver-samples/archive/master.zip
b) Välj och håll ned (eller högerklicka på) Windows-driver-samples-master.zip och välj Extrahera alla. Ange en ny mapp eller bläddra till en befintlig mapp som lagrar de extraherade filerna. Du kan till exempel ange C:\WDK_Samples\ som den nya mapp där filerna extraheras.
Punkt c När filerna har extraherats går du till följande undermapp.
C:\WDK_Samples\Sysvad
Öppna drivrutinslösningen i Visual Studio
I Visual Studio väljer du Fil>öppna>projekt/lösning... och navigerar till mappen som innehåller de extraherade filerna (till exempel C:\WDK_Samples\Sysvad). Dubbelklicka på Syvad-lösningsfilen .
Leta upp Solution Explorer i Visual Studio. (Om detta inte redan är öppet väljer du Solution Explorer på menyn Visa .) I Solution Explorer kan du se en lösning som har ett antal projekt.
Ange exemplets konfiguration och plattform
I Solution Explorer väljer du och håller (eller högerklickar på) lösning "sysvad" (7 av 7 projekt)och väljer Configuration Manager. Kontrollera att konfigurations- och plattformsinställningarna är desamma för de fyra projekten. Som standard är konfigurationen inställd på "Win10 Debug" och plattformen är inställd på "Win64" för alla projekt. Om du gör några konfigurations- och/eller plattformsändringar för ett projekt måste du göra samma ändringar för de återstående tre projekten.
Not Det här labbet förutsätter att 64-bitars Windows används. Om du använder 32-bitars Windows skapar du drivrutinen för 32 bitar.
Kontrollera drivrutinssignering
Leta upp TabletAudioSample. Öppna Sysvad-drivrutinens egenskapssida och kontrollera att signeringsläget är inställt på >.
Drivrutinsexempel måste ändras för att använda värden som inte överlappar befintliga drivrutiner. Se Från exempelkod till produktionsdrivrutin – Vad du ska ändra i exemplen om hur du skapar ett unikt drivrutinsexempel som samexisterar med befintliga verkliga drivrutiner installerade i Windows.
Skapa exemplet med Visual Studio
I Visual Studio väljer du Build>Build Solution.
Byggfönstren bör visa ett meddelande som anger att bygget för alla sex projekt har slutförts.
Tips/Råd
Om du får ett build-felmeddelande använder du versionsfelnumret för att fastställa en korrigering. Till exempel beskriver MSBuild-fel MSB8040 hur du arbetar med spectre-minimerade bibliotek.
Leta upp de skapade drivrutinsfilerna
I Utforskaren navigerar du till mappen som innehåller de extraherade filerna för exemplet. Du kan till exempel navigera till C:\WDK_Samples\Sysvad, om det är mappen som du angav tidigare. I den mappen varierar platsen för de kompilerade drivrutinsfilerna beroende på de konfigurations- och plattformsinställningar som du valde i Configuration Manager. Om du till exempel har lämnat standardinställningarna oförändrade sparas de kompilerade drivrutinsfilerna i en mapp med namnet \x64\Debug för en 64-bitars felsökningsversion.
Navigera till mappen som innehåller de skapade filerna för TabletAudioSample-drivrutinen:
C:\WDK_Samples\Sysvad\TabletAudioSample\x64\Debug. Mappen innehåller TabletAudioSample-.SYS drivrutin, pdp-symbolfilen och inf-filen. Du måste också hitta dll:erna DelayAPO, KWSApo och KeywordDetectorContosoAdapter och symbolfilerna.
För att installera drivrutinen behöver du följande filer.
Filnamn Beskrivning TabletAudioSample.sys Drivrutinsfilen. TabletAudioSample.pdb Drivrutinssymbolfilen. tabletaudiosample.inf En inf-fil (information) som innehåller information som behövs för att installera drivrutinen. KeywordDetectorContosoAdapter.dll Ett exempel på nyckelordsdetektor. KeywordDetectorContosoAdapter.pdb Exempelnyckelordsdetektorens symbolfil. DelayAPO.dll Ett fördröjningsexempel APO. DelayAPO.pdb Fördröjningsfilen för APO-symbolen. KWSApo.dll Ett exempel på ett APO för nyckelordssp spotter. KWSApo.pdb Symbolfilen för nyckelordsigenkännare. TabletAudioSample.cer Certifikatfilen för TabletAudioSample. Leta upp ett USB-minne eller konfigurera en nätverksdelning för att kopiera de byggda drivrutinsfilerna från värden till målsystemet.
I nästa avsnitt kopierar du koden till målsystemet och installerar och testar drivrutinen.
Avsnitt 4: Installera sysvad-ljuddrivrutinsexemplet på målsystemet
I avsnitt 4 använder du devcon för att installera ljuddrivrutinen Sysvad.
–> I målsystemet
Den dator där du installerar drivrutinen kallas måldator eller testdator. Det här är vanligtvis en separat dator från den dator där du utvecklar och skapar drivrutinspaketet. Den dator där du utvecklar och skapar drivrutinen kallas värddator.
Processen att flytta drivrutinspaketet till måldatorn och installera drivrutinen kallas distribution av drivrutinen.
Innan du distribuerar en drivrutin måste du förbereda måldatorn genom att aktivera testsignering. Därefter är du redo att köra det byggda drivrutinsexemplet i målsystemet.
Utför följande steg för att installera drivrutinen i målsystemet.
Aktivera testsignerade drivrutiner
Så här aktiverar du möjligheten att köra testsignerade drivrutiner:
Öppna Windows-inställningar.
I Update and Securityväljer du Recovery.
Under Avancerad startväljer du Starta om nu.
När datorn startas om väljer du Felsök.
Välj sedan Avancerade alternativ, Startinställningar och välj sedan Starta om.
Välj Inaktivera tvingande av drivrutinssignatur genom att trycka på F7-tangenten .
Datorn börjar med de nya värdena på plats.
–> I målsystemet
Installera drivrutinen
Följande instruktioner visar hur du installerar och testar exempeldrivrutinen.
INF-filen som krävs för att installera den här drivrutinen är TabletAudioSample.inf. Öppna ett kommandotolksfönster som administratör på måldatorn. Gå till mappen för drivrutinspaketet, högerklicka på filen TabletAudioSample.inf och välj sedan Installera.
Ett dialogruta visas som indikerar att testdrivrutinen är en osignerad drivrutin. Välj Installera den här drivrutinen ändå för att fortsätta.
Tips/Råd
Om du har problem med installationen kontrollerar du följande fil för mer information.
%windir%\inf\setupapi.dev.logMer detaljerade instruktioner finns i Konfigurera en dator för drivrutinsdistribution, testning och felsökning.
INF-filen innehåller maskinvaru-ID:t för att installera tabletaudiosample.sys. För Syvad-exemplet är maskinvaru-ID:t:
root\sysvad_TabletAudioSampleGranska drivrutinen i Enhetshanteraren
På måldatorn går du till kommandotolken och anger devmgmt för att öppna Enhetshanteraren. I Enhetshanteraren går du till menyn Visa och väljer Enheter efter typ.
Leta reda på Virtuell ljudenhet (WDM) – Tablet Sample i noden Ljudenhet i enhetsträdet. Detta är vanligtvis under noden Ljud-, video- och spelkontrollanter . Bekräfta att den är installerad och aktiv.
Markera drivrutinen för den faktiska maskinvaran på datorn i Enhetshanteraren. Välj och håll sedan (eller högerklicka) drivrutinen och välj inaktivera för att inaktivera drivrutinen.
Bekräfta i Enhetshanteraren att drivrutinen för ljudmaskinvara visar en nedåtpil som anger att den är inaktiverad.
När du har installerat exempeldrivrutinen är du nu redo att testa den.
Testa ljuddrivrutinen Sysvad
På måldatorn går du till kommandotolken och anger devmgmt för att öppna Enhetshanteraren. I Enhetshanteraren går du till menyn Visa och väljer Enheter efter typ. Leta reda på Virtuell ljudenhet (WDM) – Tablettexempel i enhetsträdet.
Öppna Kontrollpanelen och gå till Maskinvara och ljud>Hantera ljudenheter. I dialogrutan Ljud väljer du talarikonen med etiketten Virtuell ljudenhet (WDM) – Tablettexempel och väljer sedan Ange standard, men välj inte OK. Då hålls dialogrutan Ljud öppen.
Leta upp en MP3- eller annan ljudfil på måldatorn och dubbelklicka för att spela upp den. I dialogrutan Ljud kontrollerar du sedan att det finns aktivitet i volymnivåindikatorn som är associerad med drivrutinen Virtuell ljudenhet (WDM) – Surfplatta .
Avsnitt 5: Använd WinDbg för att visa information om drivrutinen
I avsnitt 5 anger du symbolsökvägen och använder kernelbugger-kommandon för att visa information om Sysvad-exempeldrivrutinen.
Med symboler kan WinDbg visa ytterligare information, till exempel variabelnamn, som kan vara ovärderliga vid felsökning. WinDbg använder microsoft Visual Studio-felsökningssymbolformat för felsökning på källnivå. Den kan komma åt valfri symbol eller variabel från en modul som har PDB-symbolfiler.
För att ladda felsökningsprogrammet, utför följande steg.
<-På värdsystemet
Om du stängde felsökningsprogrammet öppnar du det igen med hjälp av följande kommando i kommandotolken för administratören. Ersätt nyckeln och porten med det du tidigare konfigurerade.
C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874pAnvänd Ctrl+Break (Rullningslås) för att bryta sig in i koden som körs i målsystemet.
Ange symbolsökvägen
Om du vill ange symbolsökvägen till Microsoft-symbolservern i WinDbg-miljön använder du kommandot .symfix .
0: kd> .symfixOm du vill lägga till din lokala symbolplats för att använda dina lokala symboler, ange sökvägen genom .sympath+ och sedan .reload /f.
0: kd> .sympath+ C:\WDK_Samples\Sysvad 0: kd> .reload /fObservera Kommandot .reload med force-alternativet /f tar bort all symbolinformation för den angivna modulen och läser in symbolerna igen. I vissa fall laddar det här kommandot också om eller avlägsnar själva modulen.
Notera Du måste läsa in rätt symboler för att använda avancerad funktionalitet som WinDbg tillhandahåller. Om du inte har symboler korrekt konfigurerade får du meddelanden som anger att symboler inte är tillgängliga när du försöker använda funktioner som är beroende av symboler.
0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.
Anteckningssymbolservrar
Det finns ett antal metoder som kan användas för att arbeta med symboler. I många situationer kan du konfigurera datorn för att komma åt symboler från en symbolserver som Microsoft tillhandahåller när de behövs. Den här genomgången förutsätter att den här metoden används. Om symbolerna i din miljö finns på en annan plats ändrar du stegen för att använda den platsen. Mer information finns i Symbolsökväg för Windows-felsökningsprogram.
Obs!Förstå krav på källkodssymboler
Om du vill utföra källfelsökning måste du skapa en kontrollerad (debug) version av binärfilerna. Kompilatorn skapar symbolfiler (.pdb-filer). Dessa symbolfiler visar felsökaren hur de binära instruktionerna motsvarar källraderna. Själva källfilerna måste också vara tillgängliga för felsökningsprogrammet.
Symbolfilerna innehåller inte källkodens text. För felsökning är det bäst om länkaren inte optimerar koden. Källfelsökning och åtkomst till lokala variabler är svårare, och ibland nästan omöjligt, om koden har optimerats. Om du har problem med att visa lokala variabler eller källrader anger du följande byggalternativ.
ange COMPILE_DEBUG=1
sätt ENABLE_OPTIMIZER=0
Skriv följande i kommandoområdet i felsökningsprogrammet för att visa information om Sysvad-drivrutinen.
0: kd> lm m tabletaudiosample v Browse full module list start end module name fffff801`14b40000 fffff801`14b86000 tabletaudiosample (private pdb symbols) C:\Debuggers\sym\TabletAudioSample.pdb\E992C4803EBE48C7B23DC1596495CE181\TabletAudioSample.pdb Loaded symbol image file: tabletaudiosample.sys Image path: \SystemRoot\system32\drivers\tabletaudiosample.sys Image name: tabletaudiosample.sys Browse all global symbols functions data Timestamp: Thu Dec 10 12:20:26 2015 (5669DE8A) CheckSum: 0004891E ...Mer information finns i lm.
Välj länken Bläddra bland alla globala symboler i felsökningsutdata för att visa information om objektsymboler som börjar med bokstaven a.
Eftersom DML är aktiverat är vissa element i resultatet klickbara länkar som du kan välja. Välj datalänken i felsökningsutdata för att visa information om objektsymboler som börjar med bokstaven a.
0: kd> x /D /f tabletaudiosample!a* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z fffff806`9adb1000 tabletaudiosample!AddDevice (struct _DRIVER_OBJECT *, struct _DEVICE_OBJECT *)För mer information, se x (Granska symboler).
Filnamnstillägget !lmi visar detaljerad information om en modul. Skriv !lmi tabletaudiosample. Dina utdata bör likna den text som visas nedan.
0: kd> !lmi tabletaudiosample Loaded Module Info: [tabletaudiosample] Module: tabletaudiosample Base Address: fffff8069ad90000 Image Name: tabletaudiosample.sys Machine Type: 34404 (X64) Time Stamp: 58ebe848 Mon Apr 10 13:17:12 2017 Size: 48000 CheckSum: 42df7 Characteristics: 22 Debug Data Dirs: Type Size VA Pointer CODEVIEW a7, e5f4, d1f4 RSDS - GUID: {5395F0C5-AE50-4C56-AD31-DD5473BD318F} Age: 1, Pdb: C:\Windows-driver-samples-master\audio\sysvad\TabletAudioSample\x64\Debug\TabletAudioSample.pdb ?? 250, e69c, d29c [Data not mapped] Image Type: MEMORY - Image read successfully from loaded memory. Symbol Type: PDB - Symbols loaded successfully from image header. C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sym\TabletAudioSample.pdb\5395F0C5AE504C56AD31DD5473BD318F1\TabletAudioSample.pdb Compiler: Resource - front end [0.0 bld 0] - back end [14.0 bld 24210] Load Report: private symbols & lines, not source indexed C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sym\TabletAudioSample.pdb\5395F0C5AE504C56AD31DD5473BD318F1\TabletAudioSample.pdbAnvänd !dh-tillägget för att visa rubrikinformation enligt nedan.
0: kd> !dh tabletaudiosample File Type: EXECUTABLE IMAGE FILE HEADER VALUES 8664 machine (X64) 9 number of sections 5669DE8A time date stamp Thu Dec 10 12:20:26 2015 0 file pointer to symbol table 0 number of symbols F0 size of optional header 22 characteristics Executable App can handle >2gb addresses ...
Avsnitt 6: Visa information om plug and play-enhetens träd
I avsnitt 6 visar du information om Sysvad-exempelenhetsdrivrutinen och var den finns i enhetsträdet Plug and Play.
Information om enhetsdrivrutinen i plug and play-enhetsträdet kan vara användbar för felsökning. Om en enhetsdrivrutin till exempel inte finns i enhetsträdet kan det uppstå problem med installationen av drivrutinen.
Mer information om felsökningstillägget för enhetsnoder finns i !devnode.
<-På värdsystemet
Om du vill se alla enhetsnoder i enhetsträdet Plug and Play anger du kommandot !devnode 0 1 . Det kan ta en minut eller två att köra det här kommandot. Under den tiden visas "*Upptagen" i statusområdet för WinDbg.
0: kd> !devnode 0 1 Dumping IopRootDeviceNode (= 0xffffe0005a3a8d30) DevNode 0xffffe0005a3a8d30 for PDO 0xffffe0005a3a9e50 InstancePath is "HTREE\ROOT\0" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a3a3d30 for PDO 0xffffe0005a3a4e50 InstancePath is "ROOT\volmgr\0000" ServiceName is "volmgr" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe0005a324560 for PDO 0xffffe0005bd95ca0… ...Använd Ctrl+F för att söka i utdata som genereras för att leta efter namnet på enhetsdrivrutinen sysvad.
En post för enhetsnod med namnet
sysvad_TabletAudioSamplekommer att finnas i !devnode output för Syvad.DevNode 0xffffe00086e68190 for PDO 0xffffe00089c575a0 InstancePath is "ROOT\sysvad_TabletAudioSample\0000" ServiceName is "sysvad_tabletaudiosample" State = DeviceNodeStarted (0x308) ...Observera att PDO-adressen och DevNode-adressen visas.
!devnode 0 1 sysvad_TabletAudioSampleAnvänd kommandot för att visa Plug and Play-information som är associerad med vår Sysvad-enhetsdrivrutin.0: kd> !devnode 0 1 sysvad_TabletAudioSample Dumping IopRootDeviceNode (= 0xffffe00082df8d30) DevNode 0xffffe00086e68190 for PDO 0xffffe00089c575a0 InstancePath is "ROOT\sysvad_TabletAudioSample\0000" ServiceName is "sysvad_tabletaudiosample" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe000897fb650 for PDO 0xffffe00089927e30 InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{64097438-cdc0-4007-a19e-62e789062e20}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe00086d2f5f0 for PDO 0xffffe00089939ae0 InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{78880f4e-9571-44a4-a9df-960bde446487}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe00089759bb0 for PDO 0xffffe000875aa060 InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{7cad07f2-d0a0-4b9b-8100-8dc735e9c447}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe00087735010 for PDO 0xffffe000872068c0 InstancePath is "SWD\MMDEVAPI\{0.0.0.00000000}.{fc38551b-e69f-4b86-9661-ae6da78bc3c6}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe00088457670 for PDO 0xffffe0008562b830 InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{0894b831-c9fe-4c56-86a6-092380fc5628}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe000893dbb70 for PDO 0xffffe00089d68060 InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{15eb6b5c-aa54-47b8-959a-0cff2c1500db}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe00088e6f250 for PDO 0xffffe00089f6e990 InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{778c07f0-af9f-43f2-8b8d-490024f87239}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) DevNode 0xffffe000862eb4b0 for PDO 0xffffe000884443a0 InstancePath is "SWD\MMDEVAPI\{0.0.1.00000000}.{e4b72c7c-be50-45df-94f5-0f2922b85983}" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307)Utdata som visas i föregående kommando innehåller den PDO som är associerad med den instans av drivrutinen som körs. I det här exemplet är den 0xffffe00089c575a0. Ange kommandot !devobj<PDO-adress> för att visa Plug and Play-information som är associerad med Sysvad-enhetsdrivrutinen. Använd den PDO-adress som !devnode visar på datorn, inte den som visas här.
0: kd> !devobj 0xffffe00089c575a0 Device object (ffffe00089c575a0) is for: 0000004e \Driver\PnpManager DriverObject ffffe00082d47e60 Current Irp 00000000 RefCount 65 Type 0000001d Flags 00001040 SecurityDescriptor ffffc102b0f6d171 DevExt 00000000 DevObjExt ffffe00089c576f0 DevNode ffffe00086e68190 ExtensionFlags (0000000000) Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN AttachedDevice (Upper) ffffe00088386a50 \Driver\sysvad_tabletaudiosample Device queue is not busy.Utdata som visas i kommandot !devobj innehåller namnet på den anslutna enheten: \Driver\sysvad_tabletaudiosample. Använd kommandot !drvobj med en bitmask på 2 för att visa information som är associerad med den anslutna enheten.
0: kd> !drvobj \Driver\sysvad_tabletaudiosample 2 Driver object (ffffe0008834f670) is for: \Driver\sysvad_tabletaudiosample DriverEntry: fffff80114b45310 tabletaudiosample!FxDriverEntry DriverStartIo: 00000000 DriverUnload: fffff80114b5fea0 tabletaudiosample!DriverUnload AddDevice: fffff80114b5f000 tabletaudiosample!AddDevice Dispatch routines: [00] IRP_MJ_CREATE fffff80117b49a20 portcls!DispatchCreate [01] IRP_MJ_CREATE_NAMED_PIPE fffff8015a949a00 nt!IopInvalidDeviceRequest [02] IRP_MJ_CLOSE fffff80115e26f90 ks!DispatchCleanup [03] IRP_MJ_READ fffff80115e32710 ks!DispatchRead [04] IRP_MJ_WRITE fffff80115e327e0 ks!DispatchWrite [05] IRP_MJ_QUERY_INFORMATION fffff8015a949a00 nt!IopInvalidDeviceRequest [06] IRP_MJ_SET_INFORMATION fffff8015a949a00 nt!IopInvalidDeviceRequest [07] IRP_MJ_QUERY_EA fffff8015a949a00 nt!IopInvalidDeviceRequest [08] IRP_MJ_SET_EA fffff8015a949a00 nt!IopInvalidDeviceRequest [09] IRP_MJ_FLUSH_BUFFERS fffff80115e32640 ks!DispatchFlush [0a] IRP_MJ_QUERY_VOLUME_INFORMATION fffff8015a949a00 nt!IopInvalidDeviceRequest [0b] IRP_MJ_SET_VOLUME_INFORMATION fffff8015a949a00 nt!IopInvalidDeviceRequest [0c] IRP_MJ_DIRECTORY_CONTROL fffff8015a949a00 nt!IopInvalidDeviceRequest [0d] IRP_MJ_FILE_SYSTEM_CONTROL fffff8015a949a00 nt!IopInvalidDeviceRequest [0e] IRP_MJ_DEVICE_CONTROL fffff80115e27480 ks!DispatchDeviceIoControl [0f] IRP_MJ_INTERNAL_DEVICE_CONTROL fffff8015a949a00 nt!IopInvalidDeviceRequest [10] IRP_MJ_SHUTDOWN fffff8015a949a00 nt!IopInvalidDeviceRequest [11] IRP_MJ_LOCK_CONTROL fffff8015a949a00 nt!IopInvalidDeviceRequest [12] IRP_MJ_CLEANUP fffff8015a949a00 nt!IopInvalidDeviceRequest [13] IRP_MJ_CREATE_MAILSLOT fffff8015a949a00 nt!IopInvalidDeviceRequest [14] IRP_MJ_QUERY_SECURITY fffff80115e326a0 ks!DispatchQuerySecurity [15] IRP_MJ_SET_SECURITY fffff80115e32770 ks!DispatchSetSecurity [16] IRP_MJ_POWER fffff80117b3dce0 portcls!DispatchPower [17] IRP_MJ_SYSTEM_CONTROL fffff80117b13d30 portcls!PcWmiSystemControl [18] IRP_MJ_DEVICE_CHANGE fffff8015a949a00 nt!IopInvalidDeviceRequest [19] IRP_MJ_QUERY_QUOTA fffff8015a949a00 nt!IopInvalidDeviceRequest [1a] IRP_MJ_SET_QUOTA fffff8015a949a00 nt!IopInvalidDeviceRequest [1b] IRP_MJ_PNP fffff80114b5f7d0 tabletaudiosample!PnpHandlerAnge > för att visa Plug and Play-information som är associerad med enhetsdrivrutinen. Utdata som visas i kommandot !devnode 0 1 innehåller den PDO-adress som är associerad med den instans av drivrutinen som körs. I det här exemplet är det 0xffffe00089c575a0. Använd den PDO-adress som !devnode visar på datorn, inte den som visas nedan.
0: kd> !devstack 0xffffe00089c575a0 !DevObj !DrvObj !DevExt ObjectName ffffe00088d212e0 \Driver\ksthunk ffffe00088d21430 0000007b ffffe00088386a50 \Driver\sysvad_tabletaudiosampleffffe00088386ba0 0000007a > ffffe00089c575a0 \Driver\PnpManager 00000000 0000004e !DevNode ffffe00086e68190 : DeviceInst is "ROOT\sysvad_TabletAudioSample\0000" ServiceName is "sysvad_tabletaudiosample"
Utdata visar att vi har en mycket enkel enhetsdrivrutinsstack. Drivrutinen sysvad_TabletAudioSample är en undernod till PnPManager. PnPManager är en rotnod.
Det här diagrammet visar ett mer komplext enhetsnodträd.
Not Mer information om mer komplexa drivrutinsstackar finns i Drivrutinsstackar och Enhetsnoder och enhetsstackar.
Avsnitt 7: Arbeta med brytpunkter
I avsnitt 7 arbetar du med brytpunkter för att stoppa kodkörningen vid specifika punkter.
Ange brytpunkter med hjälp av kommandon
Brytpunkter används för att stoppa kodkörning på en viss kodrad. Du kan sedan gå vidare i koden från den punkten för att felsöka det specifika kodavsnittet.
Om du vill ange en brytpunkt med hjälp av ett felsökningskommando använder du något av följande b-kommandon .
Bp |
Anger en brytpunkt som ska vara aktiv tills modulen den finns i avladdas. |
Bu |
Anger en brytpunkt som inte är löst när modulen tas bort och återaktiveras när modulen laddas in igen. |
Bm |
Anger en brytpunkt för en symbol. Det här kommandot använder bu eller bp på rätt sätt och tillåter jokertecken * att användas för att ange brytpunkter för varje symbol som matchar (som alla metoder i en klass). |
Använd WinDbg-användargränssnittet för att bekräfta att Debug>Source Mode är aktiverat i den aktuella WinDbg-sessionen.
Lägg till din lokala kodplats i källsökvägen genom att skriva följande kommando.
.sympath+ C:\WDK_Samples\SysvadLägg till din lokala symbolplats i symbolsökvägen genom att skriva följande kommando.
.sympath+ C:\WDK_Samples\SysvadAnge felsökningsmasken
När du arbetar med en drivrutin kan det vara praktiskt att se alla meddelanden som visas. Skriv följande för att ändra standardmasken för felsökningsbit så att alla felsökningsmeddelanden från målsystemet visas i felsökningsprogrammet.
0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFFAnge brytpunkten med kommandot bm med hjälp av namnet på drivrutinen följt av funktionsnamnet (AddDevice) där du vill ange brytpunkten, avgränsad med ett utropstecken.
0: kd> bm tabletaudiosample!AddDevice breakpoint 1 redefined 1: fffff801`14b5f000 @!"tabletaudiosample!AddDevice"Du kan använda olika syntax tillsammans med att ange variabler som <modul>!<symbol>, <klass>::<metod>,'<file.cpp>:<radnummer>', eller hoppa över ett antal gånger <villkor><#>. Mer information finns i Använda brytpunkter.
Visa en lista över de aktuella brytpunkterna för att bekräfta att brytpunkten har angetts genom att skriva kommandot bl .
0: kd> bl 1 e fffff801`14b5f000 0001 (0001) tabletaudiosample!AddDeviceStarta om kodkörningen i målsystemet genom att skriva go-kommandot g.
->I målsystemet
I Windows öppnar du Enhetshanteraren med hjälp av ikonen eller genom att ange mmc devmgmt.msc. I Enhetshanteraren expanderar du noden Ljud-, video- och spelstyrenheter . Välj och håll (eller högerklicka) posten för den virtuella ljuddrivrutinen och välj Inaktivera på menyn.
Välj och håll (eller högerklicka) posten för den virtuella ljuddrivrutinen igen och välj Aktivera på menyn.
<– På värdsystemet
Detta bör göra att Windows läser in drivrutinen igen, vilket anropar AddDevice. Detta gör att felsökningsbrytpunkten AddDevice utlöses och körningen av drivrutinskoden i målsystemet stoppas.
Breakpoint 1 hit tabletaudiosample!AddDevice: fffff801`14baf000 4889542410 mov qword ptr [rsp+10h],rdxOm källsökvägen har angetts korrekt bör du stanna vid addDevice-rutinen i adapter.cpp
{ PAGED_CODE(); NTSTATUS ntStatus; ULONG maxObjects; DPF(D_TERSE, ("[AddDevice]")); maxObjects = g_MaxMiniports; #ifdef SYSVAD_BTH_BYPASS // // Allow three (3) Bluetooth hands-free profile devices. // maxObjects += g_MaxBthHfpMiniports * 3; #endif // SYSVAD_BTH_BYPASS // Tell the class driver to add the device. // ntStatus = PcAddAdapterDevice ( DriverObject, PhysicalDeviceObject, PCPFNSTARTDEVICE(StartDevice), maxObjects, 0 ); return ntStatus; } // AddDeviceStega rad för rad genom koden genom att skriva p-kommandot eller trycka på F10. Du kan gå vidare från sysvad AddDevice-koden till PpvUtilCall, PnpCallAddDevice och sedan till PipCallDriverAddDevice Windows-koden. Du kan ange ett tal till p-kommandot för att gå vidare med flera rader, till exempel p 5.
När du är klar med att stega igenom koden använder du go-kommandot g för att starta om körningen på målsystemet.
Ange brytpunkter för minnesåtkomst
Du kan också ange brytpunkter som utlöses när en minnesplats används. Använd kommandot ba (break on access) med följande syntax.
ba <access> <size> <address> {options}
| Alternativ | Beskrivning |
|---|---|
e |
execute (när CPU hämtar en instruktion från adressen) |
r |
läs/skriv (när en CPU läser eller skriver till adressen) |
w |
skriv (när processorn skriver till adressen) |
Observera att du bara kan ange fyra databrytpunkter vid varje given tidpunkt och det är upp till dig att se till att du justerar dina data korrekt, annars kommer du inte att utlösa brytpunkten (ord måste sluta i adresser som är delbara med 2, dwords måste vara delbara med 4, och fyrord med adresser som slutar på 0 eller 8)
Om du till exempel vill ange en brytpunkt för läsning/skrivning på en specifik minnesadress använder du ett kommando som detta.
ba r 4 fffff800`7bc9eff0
Ändra brytpunktstillstånd
Du kan ändra befintliga brytpunkter med hjälp av följande kommandon.
Bl |
Listar brytpunkter. |
fvt |
Rensar en brytpunkt från listan. Använd bc * för att rensa alla brytpunkter. |
Bd |
Inaktiverar en brytpunkt. Använd bd * för att inaktivera alla brytpunkter. |
vara |
Aktiverar en brytpunkt. Använd kommandot * för att aktivera alla brytpunkter. |
Du kan också ändra brytpunkter genom att välja redigera>brytpunkter. Observera att dialogrutan för brytpunkter endast fungerar med befintliga brytpunkter. Nya brytpunkter måste anges från kommandoraden.
Ange en brytpunkt på MixerVolume
Olika delar av ljuddrivrutinskoden anropas för att svara på olika händelser efter att enhetsdrivrutinen har lästs in. I nästa avsnitt anger vi en brytpunkt som utlöses när användaren justerar volymkontrollen för den virtuella ljuddrivrutinen.
Utför följande steg för att ange en brytpunkt på MixerVolume.
<– På värdsystemet
Om du vill hitta metoden som ändrar volymen använder du x-kommandot för att visa symbolerna i CAdapterCommon, som innehåller strängvolymen.
kd> x tabletaudiosample!CAdapterCommon::* ... fffff800`7bce26a0 tabletaudiosample!CAdapterCommon::MixerVolumeWrite (unsigned long, unsigned long, long) …Använd CTRL+F för att söka uppåt i utdata för volymen och leta upp metoden MixerVolumeWrite.
Rensa de tidigare brytpunkterna med bc *.
Ange en symbolbrytpunkt i rutinen CAdapterCommon::MixerVolumeWrite med hjälp av följande kommando.
kd> bm tabletaudiosample!CAdapterCommon::MixerVolumeWrite 1: fffff801`177b26a0 @!"tabletaudiosample!CAdapterCommon::MixerVolumeWrite"Ange brytpunkterna för att bekräfta att brytpunkten har angetts korrekt.
kd> bl 1 e fffff801`177b26a0 [c:\WDK_Samples\audio\sysvad\common.cpp @ 1668] 0001 (0001) tabletaudiosample!CAdapterCommon::MixerVolumeWriteStarta om kodkörningen i målsystemet genom att skriva go-kommandot g.
På Kontrollpanelen väljer du Maskinvara och Ljudljud>. Välj och håll ned (eller högerklicka på) Sinkexempelbeskrivning och välj Egenskaper. Välj fliken Nivåer . Justera skjutreglagevolymen.
Detta bör leda till att felsökningsbrytpunkten SetMixerVolume utlöses och körningen av drivrutinskoden i målsystemet stoppas.
kd> g Breakpoint 1 hit tabletaudiosample!CAdapterCommon::MixerVolumeWrite: fffff801`177b26a0 44894c2420 mov dword ptr [rsp+20h],r9dDu bör stanna vid den här raden i common.cpp
{ if (m_pHW) { m_pHW->SetMixerVolume(Index, Channel, Value); } } // MixerVolumeWriteAnvänd dv-kommandot för att visa aktuella variabler och deras värden. Mer information om variabler finns i nästa avsnitt i den här labbuppgiften.
2: kd> dv this = 0x00000000`00000010 ulNode = 0x344 ulChannel = 0x210a45f8 lVolume = 0n24Tryck F10 för att enkelt stega igenom koden.
Tryck på F5 för att slutföra körningen av MixerVolumeWrite-koden.
Sammanfattning – Stega igenom kod från felsökningskommandofönstret
Följande är de kommandon som du kan använda för att gå igenom koden (med de associerade kortkommandon som visas inom parenteser).
Bryt in (Ctrl+Break) – Det här kommandot avbryter ett system så länge systemet körs och kommunicerar med WinDbg (sekvensen i kernelfelsökaren är Ctrl+C).
Steg över (F10) – Det här kommandot gör att kodens exekvering fortsätter med ett uttalande eller en instruktion i taget. När ett anrop påträffas, fortsätter kodkörningen förbi anropet utan att gå in i den anropade rutinen. (Om programmeringsspråket är C eller C++ och WinDbg är i källläge kan källläget aktiveras eller inaktiveras med felsökning>Källläge).
Steg i (F11) – Det här kommandot liknar step-over, förutom att det låter körningen av ett anrop gå in i den anropade rutinen.
Steg ut (Shift+F11) – Det här kommandot gör att exekveringen fortsätter och avslutas från aktuell rutin (nuvarande plats i anropsstacken). Detta är användbart om du har sett tillräckligt med rutin.
Kör till markören (F7 eller Ctrl+F10) – Placera markören i ett käll- eller demonteringsfönster där du vill att körningen ska brytas och tryck sedan på F7 eller Ctrl+F10. Kodkörningen fortsätter till den punkten. Observera att om flödet av kodkörning inte når den punkt som anges av markören (t.ex. om en IF-instruktion inte körs) skulle WinDbg inte brytas eftersom kodkörningen inte nådde den angivna punkten.
Kör (F5) – Kör tills en brytpunkt påträffas eller en händelse som en buggkontroll inträffar.
Avancerade alternativ
Ange instruktionen till den aktuella raden (Ctrl+Skift+I) – I ett källfönster kan du placera markören på en rad, ange den här kortkommandot och kodkörningen startar från den punkten så fort du låter den fortsätta (till exempel med F5 eller F10). Detta är praktiskt om du vill försöka en sekvens igen, men det kräver viss försiktighet. Till exempel är register och variabler inte inställda på vad de skulle vara om kodkörningen naturligt hade nått den raden.
Direkt inställning av eip-registret – Du kan placera ett värde i eip-registret, och så fort du trycker på F5 (eller F10, F11 osv.) påbörjas körningen från den adressen. Detta liknar att ange en instruktion på den nuvarande markörraden, förutom att du specificerar adressen för en assemblerinstruktion.
Det kan vara enklare att gå igenom användargränssnittet i stället för från kommandoraden, så den här metoden rekommenderas. Vid behov kan följande kommandon användas för att gå igenom en källfil på kommandoraden:
.lines – Aktivera källradsinformation.
bp main – Ange den första brytpunkten i början av modulen.
l+t – Stegning kommer att göras enligt källraden.
Välj Felsök>källläge för att ange källläge.
L+tKommandot räcker inte.l+s – Källrader visas vid uppmaning.
g – Kör programmet tills "main" har angetts.
p – Kör en rad i källkoden.
Mer information finns i Källkodsfelsökning i WinDbg (klassisk) i felsökningsreferensdokumentationen.
Ange brytpunkter i kod
Du kan ange en brytpunkt i kod genom att lägga till -instruktionen DebugBreak() och återskapa projektet och installera om drivrutinen. Den här brytpunkten utlöses varje gång drivrutinen aktiveras, så det skulle vara en teknik som ska användas i de tidiga utvecklingsstegen, inte i produktionskoden. Den här tekniken är inte lika flexibel som att dynamiskt ange brytpunkter med hjälp av brytpunktskommandona.
Tips: Du kanske vill behålla en kopia av Sysvad-drivrutinen utan att brytpunkten har lagts till för ytterligare labbarbete.
Ange en brytning varje gång metoden AddDevice körs genom att lägga till -instruktionen
DebugBreak()i exempelkoden.... // Insert the DebugBreak() statment before the PcAddAdapterDevice is called. // DebugBreak() // Tell the class driver to add the device. // ntStatus = PcAddAdapterDevice ( DriverObject, PhysicalDeviceObject, PCPFNSTARTDEVICE(StartDevice), maxObjects, 0 ); return ntStatus; } // AddDeviceFölj alla steg som tidigare beskrivits för att återskapa drivrutinen i Microsoft Visual Studio och installera om den på måldatorn. Se till att avinstallera den befintliga drivrutinen innan du installerar den uppdaterade drivrutinen.
Rensa eventuella tidigare brytpunkter och kontrollera att felsökningsprogrammet är kopplat till måldatorn.
När koden körs och når
DebugBreak-instruktionen, kommer körningen att stoppas och ett meddelande visas.KERNELBASE!DebugBreak: 77b3b770 defe __debugbreak
Avsnitt 8: Visa variabler
I avsnitt 8 använder du felsökningskommandon för att visa variabler.
Det kan vara användbart att undersöka variabler när koden körs för att bekräfta att koden fungerar som förväntat. Den här labbuppgiften undersöker variabler när ljuddrivrutinen genererar ljud.
Använd dv-kommandot för att undersöka regionvariablerna som är associerade med tabletaudiosample!CMiniportWaveRT::New*.
kd> dv tabletaudiosample!CMiniportWaveRT::New*Rensa föregående brytpunkter
bc *Ange en symbolbrytpunkt i CMiniportWaveCyclicStreamMSVAD-rutinerna med hjälp av följande kommando.
0: kd> bm tabletaudiosample!CMiniportWaveRT::NewStream 1: fffff801`177dffc0 @!"tabletaudiosample!CMiniportWaveRT::NewStream"Starta om kodkörningen i målsystemet genom att skriva go-kommandot g.
–> I målsystemet
Leta upp en liten mediefil (till exempel Ljudfil för Windows-meddelanden med ett .wav filnamnstillägg) och välj den fil som ska spelas upp. Du kan till exempel använda Ring05.wav som finns i katalogen Windows\Media.
<– På värdsystemet
När mediefilen spelas upp ska brytpunkten utlösas och körningen av drivrutinskoden i målsystemet stoppas.
Breakpoint 1 hit tabletaudiosample!CMiniportWaveRT::NewStream: fffff801`177dffc0 44894c2420 mov dword ptr [rsp+20h],r9dKällkodsfönstret bör markera klammerparentesen vid ingången till funktionen NewStream.
/*++ Routine Description: The NewStream function creates a new instance of a logical stream associated with a specified physical channel. Callers of NewStream should run at IRQL PASSIVE_LEVEL. Arguments: OutStream - OuterUnknown - Pin - Capture - DataFormat - Return Value: NT status code. --*/ { ...Lokala variabler
Du kan visa namn och värden för alla lokala variabler för en viss ram genom att skriva kommandot dv.
0: kd> dv this = 0xffffe000`4436f8e0 OutStream = 0xffffe000`49d2f130 OuterUnknown = 0xffffe000`4436fa30 Pin = 0 Capture = 0x01 ' DataFormat = 0xffffe000`44227790 signalProcessingMode = {487E9220-E000-FFFF-30F1-D24900E0FFFF} ntStatus = 0n1055 stream = 0x00000000`00000200Använda DML för att visa variabler
Om du vill använda DML för att utforska variabler väljer du de understrukna elementen. Åtgärden Select skapar ett dx-kommando (Visa NatVis-uttryck) som gör att du kan öka detaljnivån för kapslade datastrukturer.
0: kd> dx -r1 (*((tabletaudiosample!CMiniportWaveRT *)0xffffe001d10b8380)) (*((tabletaudiosample!CMiniportWaveRT *)0xffffe001d10b8380)) : [Type: CMiniportWaveRT] [+0x020] m_lRefCount : 0 [+0x028] m_pUnknownOuter : 0xffffe001d1477e50 : [Type: IUnknown *] [+0x030] m_ulLoopbackAllocated : 0x2050 [+0x034] m_ulSystemAllocated : 0x180 [+0x038] m_ulOffloadAllocated : 0x0 [+0x03c] m_dwCaptureAllocatedModes : 0x0 0: kd> dx -r1 (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) : {487E9220-E000-FFFF-30F1-D24900E0FFFF} [Type: _GUID] [<Raw View>] 0: kd> dx -r1 -n (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) (*((tabletaudiosample!_GUID *)0xffffd001c8acd348)) : [Type: _GUID] [+0x000] Data1 : 0x487e9220 [+0x004] Data2 : 0xe000 [+0x006] Data3 : 0xffff [+0x008] Data4 : [Type: unsigned char [8]] 0: kd> dx -r1 -n (*((tabletaudiosample!unsigned char (*)[8])0xffffd001c8acd350)) (*((tabletaudiosample!unsigned char (*)[8])0xffffd001c8acd350)) : [Type: unsigned char [8]] [0] : 0x30 [1] : 0xf1 [2] : 0xd2 [3] : 0x49 [4] : 0x0 [5] : 0xe0 [6] : 0xff [7] : 0xffGlobala variabler
Du hittar minnesplatsen för en global variabel genom att skriva ? <variabelnamn>.
0: kd> ? signalProcessingMode Evaluate expression: -52768896396472 = ffffd001`c8acd348Detta returnerar variabelns minnesplats, i det här fallet ffffd001'c8acd348. Du kan visa innehållet på minnesplatsen genom att dumpa värdet genom att skriva dd-kommandot med hjälp av minnesplatsen som returnerades av föregående kommando.
0: kd> dd ffffd001`c8acd348 ffffd001`c8acd348 487e9220 ffffe000 49d2f130 ffffe000 ffffd001`c8acd358 4837c468 ffffe000 18221570 ffffc000 ffffd001`c8acd368 4436f8e0 ffffe000 487e9220 ffffe000 ffffd001`c8acd378 18ab145b fffff801 4837c420 ffffe000 ffffd001`c8acd388 4436f8e0 ffffe000 49d2f130 ffffe000 ffffd001`c8acd398 4436fa30 ffffe000 00000000 00000000 ffffd001`c8acd3a8 00000001 00000000 44227790 ffffe000 ffffd001`c8acd3b8 18adc7f9 fffff801 495972a0 ffffe000Du kan också använda variabelnamn med dd-kommandot .
0: kd> dd signalProcessingMode ffffd001`c8acd348 487e9220 ffffe000 49d2f130 ffffe000 ffffd001`c8acd358 4837c468 ffffe000 18221570 ffffc000 ffffd001`c8acd368 4436f8e0 ffffe000 487e9220 ffffe000 ffffd001`c8acd378 18ab145b fffff801 4837c420 ffffe000 ffffd001`c8acd388 4436f8e0 ffffe000 49d2f130 ffffe000 ffffd001`c8acd398 4436fa30 ffffe000 00000000 00000000 ffffd001`c8acd3a8 00000001 00000000 44227790 ffffe000 ffffd001`c8acd3b8 18adc7f9 fffff801 495972a0 ffffe000Visa variabler
Använd menyalternativet Visa>lokala inställningar för att visa lokala variabler. Det här gränssnittet ger också den här möjligheten att öka detaljnivån för mer komplexa datastrukturer.
Använd p eller F10 för att gå vidare med cirka 10 rader i koden tills du markerar ntStatus = IsFormatSupported(Pin, Capture, DataFormat); kodrad.
PAGED_CODE(); ASSERT(OutStream); ASSERT(DataFormat); DPF_ENTER(("[CMiniportWaveRT::NewStream]")); NTSTATUS ntStatus = STATUS_SUCCESS; PCMiniportWaveRTStream stream = NULL; GUID signalProcessingMode = AUDIO_SIGNALPROCESSINGMODE_DEFAULT; *OutStream = NULL; // // If the data format attributes were specified, extract them. // if ( DataFormat->Flags & KSDATAFORMAT_ATTRIBUTES ) { // The attributes are aligned (QWORD alignment) after the data format PKSMULTIPLE_ITEM attributes = (PKSMULTIPLE_ITEM) (((PBYTE)DataFormat) + ((DataFormat->FormatSize + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT)); ntStatus = GetAttributesFromAttributeList(attributes, attributes->Size, &signalProcessingMode); } // Check if we have enough streams. // if (NT_SUCCESS(ntStatus)) { ntStatus = ValidateStreamCreate(Pin, Capture, signalProcessingMode); } // Determine if the format is valid. // if (NT_SUCCESS(ntStatus)) { ntStatus = IsFormatSupported(Pin, Capture, DataFormat); } ...Använd dv-kommandot för att visa namn och värden för alla lokala variabler för en viss ram. Observera att värdena som förväntat skiljer sig från den senaste gången vi körde det här kommandot, eftersom ytterligare kod har körts som ändrar de lokala variablerna och vissa variabler nu inte finns i den aktuella ramen eller deras värden har ändrats.
2: kd> dv this = 0xffffe001`d1182000 OutStream = 0xffffe001`d4776d20 OuterUnknown = 0xffffe001`d4776bc8 Pin = 0 Capture = 0x00 ' DataFormat = 0xffffe001`cd7609b0 signalProcessingMode = {4780004E-7133-41D8-8C74-660DADD2C0EE} ntStatus = 0n0 stream = 0x00000000`00000000
Avsnitt 9: Visa anropsstackar
I avsnitt 9 visar du anropsstackar för att undersöka uppringarens/anroparens kod.
Anropsstacken är kedjan med funktionsanrop som har lett till den aktuella platsen för programräknaren. Den översta funktionen i anropsstacken är den aktuella funktionen och nästa funktion är den funktion som anropade den aktuella funktionen och så vidare.
Om du vill visa anropsstacken använder du k*-kommandona:
Kb |
Visar stacken och de tre första parametrarna. |
Kp |
Visar staplarna och den fullständiga listan med parametrar. |
Kn |
Gör att du kan se stacken med raminformationen bredvid den. |
Om du vill hålla anropsstacken tillgänglig kan du välja Visasamtalsstack> för att visa den. Välj kolumnerna överst i fönstret för att växla visning av ytterligare information.
Dessa resultat visar anropsstacken när du felsöker exempeladapterkoden i ett pausläge.
0: kd> kb
# RetAddr : Args to Child : Call Site
00 fffff800`7a0fa607 : ffffe001`d1182000 ffffe001`d4776d20 ffffe001`d4776bc8 ffffe001`00000000 : tabletaudiosample!CMiniportWaveRT::NewStream+0x1dc [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 597]
01 fffff800`7a0fb2c3 : 00000000`00000000 ffffe001`d122bb10 ffffe001`ceb81750 ffffe001`d173f058 : portcls!CPortPinWaveRT::Init+0x2e7
02 fffff800`7a0fc7f9 : ffffe001`d4776bc0 00000000`00000000 ffffe001`d10b8380 ffffe001`d122bb10 : portcls!CPortFilterWaveRT::NewIrpTarget+0x193
03 fffff800`7a180552 : 00000000`00000000 ffffe001`d10b8380 ffffe001`d122bb10 ffffe001`d4565600 : portcls!xDispatchCreate+0xd9
04 fffff800`7a109a9a : ffffe001`d10b84d0 ffffe001`d10b8380 00000000`00000000 ffffe001`00000000 : ks!KsDispatchIrp+0x272
05 fffff800`7bd314b1 : ffffe001`d122bb10 ffffd001`c3098590 ffffe001`d122bd90 ffffe001`ce80da70 : portcls!DispatchCreate+0x7a
06 fffff803`cda1bfa8 : 00000000`00000024 00000000`00000000 00000000`00000000 ffffe001`d122bb10 : ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
07 fffff803`cda7b306 : 00000000`000001f0 ffffe001`d48ce690 ffffe001`d13d6400 ffffe001`d13d64c0 : nt!IopParseDevice+0x7c8
08 fffff803`cda12916 : 00000000`000001f0 ffffd001`c30988d0 ffffe001`d13d6490 fffff803`cda7b250 : nt!IopParseFile+0xb6
09 fffff803`cda1131c : ffffe001`d2ccb001 ffffd001`c30989e0 00ffffe0`00000040 ffffe001`cd127dc0 : nt!ObpLookupObjectName+0x776
0a fffff803`cd9fedb8 : ffffe001`00000001 ffffe001`d48ce690 00000000`00000000 00000000`00000000 : nt!ObOpenObjectByNameEx+0x1ec
0b fffff803`cd9fe919 : 000000ee`6d1fc8d8 000000ee`6d1fc788 000000ee`6d1fc7e0 000000ee`6d1fc7d0 : nt!IopCreateFile+0x3d8
0c fffff803`cd752fa3 : ffffc000`1f296870 fffff803`cd9d9fbd ffffd001`c3098be8 00000000`00000000 : nt!NtCreateFile+0x79
0d 00007fff`69805b74 : 00007fff`487484e6 0000029b`00000003 00000000`0000012e 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13
0e 00007fff`487484e6 : 0000029b`00000003 00000000`0000012e 00000000`00000000 00000000`00000000 : 0x00007fff`69805b74
0f 0000029b`00000003 : 00000000`0000012e 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007fff`487484e6
10 00000000`0000012e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000080 : 0x0000029b`00000003
11 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000080 00000000`00000000 : 0x12e
Du kan använda DML för att utforska koden ytterligare. När du väljer den första posten 00 används kommandot .frame (Set Local Context) för att ange kontexten och sedan visar kommandot dv (Visa lokala variabler) de lokala variablerna.
0: kd> .frame 0n0;dv /t /v
00 ffffd001`c30981d0 fffff800`7a0fa607 tabletaudiosample!CMiniportWaveRT::NewStream+0x1dc [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 597]
ffffd001`c30982b0 class CMiniportWaveRT * this = 0xffffe001`d1182000
ffffd001`c30982b8 struct IMiniportWaveRTStream ** OutStream = 0xffffe001`d4776d20
ffffd001`c30982c0 struct IPortWaveRTStream * OuterUnknown = 0xffffe001`d4776bc8
ffffd001`c30982c8 unsigned long Pin = 0
ffffd001`c30982d0 unsigned char Capture = 0x00 '
ffffd001`c30982d8 union KSDATAFORMAT * DataFormat = 0xffffe001`cd7609b0
ffffd001`c3098270 struct _GUID signalProcessingMode = {4780004E-7133-41D8-8C74-660DADD2C0EE}
ffffd001`c3098210 long ntStatus = 0n0
ffffd001`c3098218 class CMiniportWaveRTStream * stream = 0x00000000`00000000
Avsnitt 10: Visa processer och trådar
I avsnitt 10 använder du felsökningskommandon för att visa processer och trådar.
Bearbeta
Om du vill ändra den aktuella processkontexten använder du processkommandot .process<>. I följande exempel visas hur du identifierar en process och växlar kontext till den.
!processAnvänd kommandot för att visa den aktuella processen som ingår i uppspelningen av ljudet.Mer information finns i !process
Utdata visar att processen är associerad med audiodg.exe. Om du fortfarande befinner dig vid den brytpunkt som beskrivs i föregående avsnitt i detta ämne bör den aktuella processen associeras med audiodg.exe-bild.
<– På värdsystemet
0: kd> !process
PROCESS ffffe001d147c840
SessionId: 0 Cid: 10f0 Peb: ee6cf8a000 ParentCid: 0434
DirBase: d2122000 ObjectTable: ffffc0001f191ac0 HandleCount: <Data Not Accessible>
Image: audiodg.exe
VadRoot ffffe001d4222f70 Vads 70 Clone 0 Private 504. Modified 16. Locked 0.
DeviceMap ffffc00019113080
Token ffffc0001f1d4060
ElapsedTime <Invalid>
UserTime 00:00:00.000
KernelTime 00:00:00.000
QuotaPoolUsage[PagedPool] 81632
QuotaPoolUsage[NonPagedPool] 9704
Working Set Sizes (now,min,max) (2154, 1814, 2109) (8616KB, 7256KB, 8436KB)
PeakWorkingSetSize 2101
VirtualSize 2097192 Mb
PeakVirtualSize 2097192 Mb
PageFaultCount 2336
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 1573
THREAD ffffe001d173e840 Cid 10f0.1dac Teb: 000000ee6cf8b000 Win32Thread: ffffe001d1118cf0 WAIT: (UserRequest) UserMode Non-Alertable
ffffe001d16c4dd0 NotificationEvent
ffffe001d08b0840 ProcessObject
THREAD ffffe001ceb77080 Cid 10f0.16dc Teb: 000000ee6cf8d000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001cf2d1840 QueueObject
THREAD ffffe001d112c840 Cid 10f0.0a4c Teb: 000000ee6cf8f000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001cf2d1840 QueueObject
THREAD ffffe001d16c7840 Cid 10f0.13c4 Teb: 000000ee6cf91000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001cf2d1840 QueueObject
THREAD ffffe001cec67840 Cid 10f0.0dbc Teb: 000000ee6cf93000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001d173e5c0 QueueObject
THREAD ffffe001d1117840 Cid 10f0.1d6c Teb: 000000ee6cf95000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001d173e5c0 QueueObject
THREAD ffffe001cdeae840 Cid 10f0.0298 Teb: 000000ee6cf97000 Win32Thread: 0000000000000000 RUNNING on processor 2
Observera att en av de trådar som är associerade med den här processen är i körtillståndet. Den här tråden stöttade uppspelningen av medieklippet när brytpunkten inträdde.
Använd kommandot !process 0 0 för att visa sammanfattningsinformation för alla processer. I kommandoutdata använder du CTRL+F för att hitta process-ID:t för den process som är associerad med audiodg.exe-avbildningen. I exemplet nedan är process-ID ffffe001d147c840.
Registrera process-ID:t som är associerat med audiodg.exe på datorn för senare användning i den här labbuppgiften. ________________________
...
PROCESS ffffe001d147c840
SessionId: 0 Cid: 10f0 Peb: ee6cf8a000 ParentCid: 0434
DirBase: d2122000 ObjectTable: ffffc0001f191ac0 HandleCount: <Data Not Accessible>
Image: audiodg.exe
...
Ange g i felsökningsprogrammet för att köra koden framåt tills medieklippet har spelats upp. Bryt sedan in i felsökningsprogrammet genom att trycka på Ctrl+ScrLk (Ctrl+Break) Använd kommandot !process för att bekräfta att du nu kör en annan process.
!process
PROCESS ffffe001cd0ad040
SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 001aa000 ObjectTable: ffffc00017214000 HandleCount: <Data Not Accessible>
Image: System
VadRoot ffffe001d402b820 Vads 438 Clone 0 Private 13417. Modified 87866. Locked 64.
DeviceMap ffffc0001721a070
Token ffffc00017216a60
ElapsedTime 05:04:54.716
UserTime 00:00:00.000
KernelTime 00:00:20.531
QuotaPoolUsage[PagedPool] 0
QuotaPoolUsage[NonPagedPool] 0
Working Set Sizes (now,min,max) (1720, 50, 450) (6880KB, 200KB, 1800KB)
PeakWorkingSetSize 15853
VirtualSize 58 Mb
PeakVirtualSize 74 Mb
PageFaultCount 46128
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 66
THREAD ffffe001cd0295c0 Cid 0004.000c Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (Executive) KernelMode Non-Alertable
fffff803cd8e0120 SynchronizationEvent
THREAD ffffe001cd02a6c0 Cid 0004.0010 Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (Executive) KernelMode Non-Alertable
fffff803cd8e0ba0 Semaphore Limit 0x7fffffff
...
Utdata ovan visar att en annan systemprocess av ffffe001cd0ad040 körs. Bildnamnet visar System, inte audiodg.exe.
Använd nu kommandot !process för att växla till den process som var associerad med audiodg.exe. I exemplet är process-ID ffffe001d147c840. Ersätt process-ID:t i exemplet med ditt process-ID som du registrerade tidigare.
0: kd> !process ffffe001d147c840
PROCESS ffffe001d147c840
SessionId: 0 Cid: 10f0 Peb: ee6cf8a000 ParentCid: 0434
DirBase: d2122000 ObjectTable: ffffc0001f191ac0 HandleCount: <Data Not Accessible>
Image: audiodg.exe
VadRoot ffffe001d4222f70 Vads 60 Clone 0 Private 299. Modified 152. Locked 0.
DeviceMap ffffc00019113080
Token ffffc0001f1d4060
ElapsedTime 1 Day 01:53:14.490
UserTime 00:00:00.031
KernelTime 00:00:00.031
QuotaPoolUsage[PagedPool] 81552
QuotaPoolUsage[NonPagedPool] 8344
Working Set Sizes (now,min,max) (1915, 1814, 2109) (7660KB, 7256KB, 8436KB)
PeakWorkingSetSize 2116
VirtualSize 2097189 Mb
PeakVirtualSize 2097192 Mb
PageFaultCount 2464
MemoryPriority BACKGROUND
BasePriority 8
CommitCharge 1418
THREAD ffffe001d173e840 Cid 10f0.1dac Teb: 000000ee6cf8b000 Win32Thread: ffffe001d1118cf0 WAIT: (UserRequest) UserMode Non-Alertable
ffffe001d16c4dd0 NotificationEvent
ffffe001d08b0840 ProcessObject
Not impersonating
DeviceMap ffffc00019113080
Owning Process ffffe001d147c840 Image: audiodg.exe
Attached Process N/A Image: N/A
Wait Start TickCount 338852 Ticks: 197682 (0:00:51:28.781)
Context Switch Count 36 IdealProcessor: 0
UserTime 00:00:00.015
KernelTime 00:00:00.000
Win32 Start Address 0x00007ff7fb928de0
Stack Init ffffd001c2ec6dd0 Current ffffd001c2ec60c0
Base ffffd001c2ec7000 Limit ffffd001c2ec1000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
THREAD ffffe001d115c080 Cid 10f0.15b4 Teb: 000000ee6cf9b000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001d0bf0640 QueueObject
Not impersonating
DeviceMap ffffc00019113080
Owning Process ffffe001d147c840 Image: audiodg.exe
Attached Process N/A Image: N/A
Wait Start TickCount 338852 Ticks: 197682 (0:00:51:28.781)
Context Switch Count 1 IdealProcessor: 0
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x00007fff6978b350
Stack Init ffffd001c3143dd0 Current ffffd001c3143520
Base ffffd001c3144000 Limit ffffd001c313e000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
THREAD ffffe001d3a27040 Cid 10f0.17f4 Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
ffffe001d173e5c0 QueueObject
Not impersonating
DeviceMap ffffc00019113080
Owning Process ffffe001d147c840 Image: audiodg.exe
Attached Process N/A Image: N/A
Wait Start TickCount 518918 Ticks: 17616 (0:00:04:35.250)
Context Switch Count 9 IdealProcessor: 1
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x00007fff6978b350
Stack Init ffffd001c70c6dd0 Current ffffd001c70c6520
Base ffffd001c70c7000 Limit ffffd001c70c1000 Call 0
Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
Eftersom den här koden inte är aktiv är alla trådar i väntetillstånd som förväntat.
Trådar
Kommandona för att visa och ange trådar liknar processernas. Använd kommandot !thread för att visa trådar. Använd .thread för att ange aktuella trådar.
Om du vill utforska trådar som är associerade med mediespelaren spelar du upp medieklippet igen. Om brytpunkten som beskrivs i föregående avsnitt fortfarande är aktiv, kommer du att stanna vid kontexten för audiodg.exe.
Använd !thread -1 0 för att visa kort information för den aktuella tråden. Detta visar trådadressen, tråd- och process-ID:t, TEB-adressen (thread environment block), adressen till win32-funktionen (om någon) som tråden skapades för att köras och trådens schemaläggningstillstånd.
0: kd> !thread -1 0
THREAD ffffe001d3a27040 Cid 10f0.17f4 Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 RUNNING on processor 0
Om du vill visa mer information om tråden som körs skriver du !thread. Information som liknar följande bör visas.
0: kd> !thread
THREAD ffffe001d3a27040 Cid 10f0.17f4 Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 RUNNING on processor 0
IRP List:
ffffe001d429e580: (0006,02c8) Flags: 000008b4 Mdl: 00000000
Not impersonating
DeviceMap ffffc00019113080
Owning Process ffffe001d147c840 Image: audiodg.exe
Attached Process N/A Image: N/A
Wait Start TickCount 537630 Ticks: 0
Context Switch Count 63 IdealProcessor: 1
UserTime 00:00:00.000
KernelTime 00:00:00.015
Win32 Start Address 0x00007fff6978b350
Stack Init ffffd001c70c6dd0 Current ffffd001c70c6520
Base ffffd001c70c7000 Limit ffffd001c70c1000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Child-SP RetAddr : Args to Child : Call Site
ffffd001`c70c62a8 fffff800`7a0fa607 : ffffe001`d4aec5c0 ffffe001`cdefd3d8 ffffe001`d4aec5c0 ffffe001`cdefd390 : tabletaudiosample!CMiniportWaveRT::NewStream [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 562]
ffffd001`c70c62b0 fffff800`7a0fb2c3 : 00000000`00000000 ffffe001`d429e580 ffffe001`d4ea47b0 ffffe001`cdefd3d8 : portcls!CPortPinWaveRT::Init+0x2e7
ffffd001`c70c6340 fffff800`7a0fc7f9 : ffffe001`d4aec430 00000000`00000000 ffffe001`d10b8380 ffffe001`d429e580 : portcls!CPortFilterWaveRT::NewIrpTarget+0x193
ffffd001`c70c63c0 fffff800`7a180552 : 00000000`00000000 ffffe001`d10b8380 ffffe001`d429e580 ffffe001`d4565600 : portcls!xDispatchCreate+0xd9
ffffd001`c70c6450 fffff800`7a109a9a : ffffe001`d10b84d0 ffffe001`d10b8380 00000000`00000000 ffffe001`00000000 : ks!KsDispatchIrp+0x272
ffffd001`c70c6510 fffff800`7bd314b1 : ffffe001`d429e580 ffffd001`c70c6590 ffffe001`d429e800 ffffe001`ce80da70 : portcls!DispatchCreate+0x7a
ffffd001`c70c6540 fffff803`cda1bfa8 : 00000000`00000025 00000000`00000000 00000000`00000000 ffffe001`d429e580 : ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
ffffd001`c70c65a0 fffff803`cda7b306 : 00000000`000002fc ffffe001`d5e0d510 00000000`00000000 ffffe001`d3341bd0 : nt!IopParseDevice+0x7c8
ffffd001`c70c6770 fffff803`cda12916 : 00000000`000002fc ffffd001`c70c68d0 ffffe001`d3341ba0 fffff803`cda7b250 : nt!IopParseFile+0xb6
ffffd001`c70c67d0 fffff803`cda1131c : ffffe001`ceb6c601 ffffd001`c70c69e0 00000000`00000040 ffffe001`cd127dc0 : nt!ObpLookupObjectName+0x776
ffffd001`c70c6970 fffff803`cd9fedb8 : ffff8ab8`00000001 ffffe001`d5e0d510 00000000`00000000 00000000`00000000 : nt!ObOpenObjectByNameEx+0x1ec
ffffd001`c70c6a90 fffff803`cd9fe919 : 000000ee`6d37c6e8 00000004`6d37c500 000000ee`6d37c5f0 000000ee`6d37c5e0 : nt!IopCreateFile+0x3d8
ffffd001`c70c6b40 fffff803`cd752fa3 : fffff6fb`7da05360 fffff6fb`40a6c0a8 fffff681`4d815760 ffff8ab8`92895e23 : nt!NtCreateFile+0x79
ffffd001`c70c6bd0 00007fff`69805b74 : 00007fff`487484e6 0000029b`00000003 00000000`0000012e 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd001`c70c6c40)
000000ee`6d37c568 00007fff`487484e6 : 0000029b`00000003 00000000`0000012e 00000000`00000000 00000000`00000000 : 0x00007fff`69805b74
000000ee`6d37c570 0000029b`00000003 : 00000000`0000012e 00000000`00000000 00000000`00000000 00000000`00000000 : 0x00007fff`487484e6
000000ee`6d37c578 00000000`0000012e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000080 : 0x0000029b`00000003
000000ee`6d37c580 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000080 00000000`00000000 : 0x12e
Använd k-kommandot för att visa anropsstacken som är associerad med tråden.
0: kd> k
# Child-SP RetAddr Call Site
00 ffffd001`c70c62a8 fffff800`7a0fa607 tabletaudiosample!CMiniportWaveRT::NewStream [c:\data1\threshold\audio\endpointscommon\minwavert.cpp @ 562]
01 ffffd001`c70c62b0 fffff800`7a0fb2c3 portcls!CPortPinWaveRT::Init+0x2e7
02 ffffd001`c70c6340 fffff800`7a0fc7f9 portcls!CPortFilterWaveRT::NewIrpTarget+0x193
03 ffffd001`c70c63c0 fffff800`7a180552 portcls!xDispatchCreate+0xd9
04 ffffd001`c70c6450 fffff800`7a109a9a ks!KsDispatchIrp+0x272
05 ffffd001`c70c6510 fffff800`7bd314b1 portcls!DispatchCreate+0x7a
06 ffffd001`c70c6540 fffff803`cda1bfa8 ksthunk!CKernelFilterDevice::DispatchIrp+0xf9
07 ffffd001`c70c65a0 fffff803`cda7b306 nt!IopParseDevice+0x7c8
08 ffffd001`c70c6770 fffff803`cda12916 nt!IopParseFile+0xb6
09 ffffd001`c70c67d0 fffff803`cda1131c nt!ObpLookupObjectName+0x776
0a ffffd001`c70c6970 fffff803`cd9fedb8 nt!ObOpenObjectByNameEx+0x1ec
0b ffffd001`c70c6a90 fffff803`cd9fe919 nt!IopCreateFile+0x3d8
0c ffffd001`c70c6b40 fffff803`cd752fa3 nt!NtCreateFile+0x79
0d ffffd001`c70c6bd0 00007fff`69805b74 nt!KiSystemServiceCopyEnd+0x13
0e 000000ee`6d37c568 00007fff`487484e6 0x00007fff`69805b74
0f 000000ee`6d37c570 0000029b`00000003 0x00007fff`487484e6
10 000000ee`6d37c578 00000000`0000012e 0x0000029b`00000003
11 000000ee`6d37c580 00000000`00000000 0x12e
Ange g i felsökningsprogrammet för att köra koden framåt tills medieklippet har spelats upp. Bryt sedan in i felsökningsprogrammet genom att trycka på Ctrl - ScrLk (Ctrl-Break) Använd kommandot !thread för att bekräfta att du nu kör en annan tråd.
0: kd> !thread
THREAD ffffe001ce80b840 Cid 17e4.01ec Teb: 00000071fa9b9000 Win32Thread: ffffe001d41690d0 RUNNING on processor 0
Not impersonating
DeviceMap ffffc0001974e2c0
Owning Process ffffe001d1760840 Image: rundll32.exe
Attached Process N/A Image: N/A
Wait Start TickCount 538040 Ticks: 0
Context Switch Count 3181840 IdealProcessor: 0
UserTime 00:00:08.250
KernelTime 00:00:10.796
Win32 Start Address 0x00007ff6d2f24270
Stack Init ffffd001cd16afd0 Current ffffd001cd16a730
Base ffffd001cd16b000 Limit ffffd001cd165000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Child-SP RetAddr : Args to Child : Call Site
fffff803`cf373d18 fffff800`7a202852 : fffff803`cf373e60 00000000`00000001 ffffe001`cf4ed330 00000000`0000ffff : nt!DbgBreakPointWithStatus
fffff803`cf373d20 fffff803`cd6742c6 : ffffe001`cf4ed2f0 fffff803`cf373e60 00000000`00000001 00000000`0004e4b8 : kdnic!TXSendCompleteDpc+0x142
fffff803`cf373d60 fffff803`cd74d495 : 00000000`00000000 fffff803`cd923180 fffff803`cde1f4b0 fffff901`40669010 : nt!KiRetireDpcList+0x5f6
fffff803`cf373fb0 fffff803`cd74d2a0 : 00000000`00000090 0000000e`0000006a 00000000`00000092 00000000`00000000 : nt!KxRetireDpcList+0x5 (TrapFrame @ fffff803`cf373e70)
ffffd001`cd16a6c0 fffff803`cd74bd75 : 00000000`00000000 fffff803`cd74a031 00000000`00000000 00000000`00000000 : nt!KiDispatchInterruptContinue
ffffd001`cd16a6f0 fffff803`cd74a031 : 00000000`00000000 00000000`00000000 ffffe001`cff4d2a0 fffff803`cd67738e : nt!KiDpcInterruptBypass+0x25
ffffd001`cd16a700 fffff960`50cdb5a4 : fffff901`400006d0 00000000`00000001 fffff901`40000d60 ffffd001`cd16a9f0 : nt!KiInterruptDispatchNoLockNoEtw+0xb1 (TrapFrame @ ffffd001`cd16a700)
ffffd001`cd16a890 fffff960`50c66b2f : 00000000`00000000 fffff901`40669010 fffff901`42358580 fffff901`40000d60 : win32kfull!Win32FreePoolImpl+0x34
ffffd001`cd16a8c0 fffff960`50c68cd6 : 00000000`00000000 ffffd001`cd16a9f0 fffff901`400006d0 fffff901`400c0460 : win32kfull!EXLATEOBJ::vAltUnlock+0x1f
ffffd001`cd16a8f0 fffff803`cd752fa3 : 00000000`00000000 00000000`00000000 ffffe001`ce80b840 00000000`00000000 : win32kfull!NtGdiAlphaBlend+0x1d16
ffffd001`cd16add0 00007fff`674c1494 : 00007fff`674b1e97 0000a7c6`daee0559 00000000`00000001 0000020b`741f3c50 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd001`cd16ae40)
00000071`fa74c9a8 00007fff`674b1e97 : 0000a7c6`daee0559 00000000`00000001 0000020b`741f3c50 00000000`00ffffff : 0x00007fff`674c1494
00000071`fa74c9b0 0000a7c6`daee0559 : 00000000`00000001 0000020b`741f3c50 00000000`00ffffff 00000000`00000030 : 0x00007fff`674b1e97
00000071`fa74c9b8 00000000`00000001 : 0000020b`741f3c50 00000000`00ffffff 00000000`00000030 00000000`01010bff : 0x0000a7c6`daee0559
00000071`fa74c9c0 0000020b`741f3c50 : 00000000`00ffffff 00000000`00000030 00000000`01010bff 00000000`00000000 : 0x1
00000071`fa74c9c8 00000000`00ffffff : 00000000`00000030 00000000`01010bff 00000000`00000000 00000000`000000c0 : 0x0000020b`741f3c50
00000071`fa74c9d0 00000000`00000030 : 00000000`01010bff 00000000`00000000 00000000`000000c0 00000000`00000030 : 0xffffff
00000071`fa74c9d8 00000000`01010bff : 00000000`00000000 00000000`000000c0 00000000`00000030 00000071`00000030 : 0x30
00000071`fa74c9e0 00000000`00000000 : 00000000`000000c0 00000000`00000030 00000071`00000030 00000071`01ff8000 : 0x1010bff
Bildnamnet är rundll32.exe, vilket faktiskt inte är det bildnamn som är associerat med medieklippet.
Notera Om du vill ange den aktuella tråden skriver du .thread <trådnr>.
Mer information om trådar och processer finns i följande referenser:
Avsnitt 11: IRQL, register och demontering
Visa den sparade IRQL
I avsnitt 11 visar du IRQL och innehållet i regsisters.
<– På värdsystemet
Nivån för avbrottsbegäran (IRQL) används för att hantera prioriteten för avbrottsservice. Varje processor har en IRQL-inställning som trådar kan höja eller sänka. Avbrott som inträffar vid eller under processorns IRQL-inställning är maskerade och påverkar inte den aktuella åtgärden. Avbrott som inträffar ovanför processorns IRQL-inställning har företräde framför den aktuella åtgärden. !irql-tillägget visar IRQL (Interrupt Request Level) på den aktuella processorn på måldatorn innan felsökningsfelet inträffade. När måldatorn bryter sig in i felsökningsprogrammet ändras IRQL, men IRQL som var effektiv precis innan felsökningspausen sparas och visas av !irql.
0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)
< Visa registren och disassemblera
Visa registren
Visa innehållet i register för den aktuella tråden i den aktuella processorn med hjälp av kommandot r (Register).
0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
r8=000000000000003e r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc int 3
Du kan också visa innehållet i registren genom att välja View>Registers.
Att visa innehållet i registren kan vara användbart när du går igenom körningen av kod för sammansättningsspråk och i andra scenarier. Mer information finns i r (register).
Information om innehållet i registret finns i x86-arkitektur och x64-arkitektur.
Demontering
Du kan demontera koden som körs för att visa assemblerkoden som körs genom att välja Visa>Disassemblering.
Mer information om demontering av assemblerkod finns i Annotated x86 Disassembly (Kommenterad x86 Disassembly) och Annotated x64 Disassembly (Kommenterad x64 Disassembly).
Avsnitt 12: Arbeta med minne
I avsnitt 12 använder du felsökningskommandon för att visa innehållet i minnet.
Visa minne
Du kan behöva undersöka minnet för att identifiera ett problem eller för att inspektera variabler, pekare och så vidare. Du kan visa minne genom att skriva något av följande d* <adresskommandon> .
Db |
Visar data i bytevärden och ASCII-tecken. |
Dd |
Visar data som dubbla breda ord (4 byte). |
du |
Visar data som Unicode-tecken. |
Dw |
Visar data som ordvärden (2 byte) och ASCII-tecken. |
Not Om du försöker visa en ogiltig adress visas innehållet som frågetecken (?).
Du kan också visa minnet genom att välja Visa>minne. Använd rullgardinsmenyn för visningsformat för att ändra hur minnet visas.
Om du vill visa data som är associerade med volymkontrollen anger du att en brytpunkt ska utlösas för rutinen PropertyHandlerAudioEngineVolumeLevel med kommandot bm. Innan vi anger den nya brytpunkten rensar vi alla tidigare brytpunkter med bc *.
kd> bc *Ange en brytpunkt som ska utlösas för rutinen PropertyHandlerAudioEngineVolumeLevel med kommandot bm.
kd> bm tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume 1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"Ange brytpunkterna för att bekräfta att brytpunkten har angetts korrekt.
kd> bl 1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"Använd kommandot g för att starta om kodkörningen.
Justera volymen i systemfältet på målsystemet. Detta gör att brytpunkten utlöses.
Breakpoint 1 hit tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume: fffff80f`02c3a4b0 44894c2420 mov dword ptr [rsp+20h],r9dAnvänd menyalternativet Visa>lokal om du vill visa lokala variabler. Observera det aktuella värdet för variabeln IVolume.
Du kan visa datatypen och det aktuella värdet för IVolume-variabeln i exempelkoden genom att skriva dt-kommandot och namnet på variabeln.
kd> dt lVolume Local var @ 0xa011ea50 Type long 0n-6291456Brytpunkten nås när du anger SetDeviceChannelVolume.
STDMETHODIMP_(NTSTATUS) CMiniportWaveRT::SetDeviceChannelVolume(_In_ ULONG _ulNodeId, _In_ UINT32 _uiChannel, _In_ LONG _Volume) { NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; PAGED_CODE (); DPF_ENTER(("[CMiniportWaveRT::SetEndpointChannelVolume]")); IF_TRUE_ACTION_JUMP(_ulNodeId != KSNODE_WAVE_AUDIO_ENGINE, ntStatus = STATUS_INVALID_DEVICE_REQUEST, Exit); // Snap the volume level to our range of steppings. LONG lVolume = VOLUME_NORMALIZE_IN_RANGE(_Volume); ntStatus = SetChannelVolume(_uiChannel, lVolume); Exit: return ntStatus; }Försök att visa värdet på minnesplatsen för IVolume med hjälp av kommandot dt (visningstyp).
kd> dt dt lVolume Local var @ 0xffffb780b7eee664 Type long 0n0Eftersom variabeln ännu inte har definierats innehåller den inte information.
Tryck på F10 för att köra framåt till den sista kodraden i SetDeviceChannelVolume.
return ntStatus;Visa värdet på minnesplatsen för IVolume med hjälp av kommandot dt (visningstyp).
kd> dt lVolume Local var @ 0xffffb780b7eee664 Type long 0n-6291456Nu när variabeln är aktiv visas värdet 6291456 i det här exemplet.
Du kan också visa minnesplatsen för IVolume med hjälp av ? (Utvärdera uttryck) befallning.
kd> ? lVolume Evaluate expression: -79711507126684 = ffffb780`b7eee664Adressen som visas, ffffb780'b7eee664 är adressen till variabeln lVolume. Använd dd-kommandot för att visa innehållet i minnet på den platsen.
kd> dd ffffb780`b7eee664 ffffb780`b7eee664 ffa00000 00000018 00000000 c52d7008 ffffb780`b7eee674 ffffc98e e0495756 fffff80e c52d7008 ffffb780`b7eee684 ffffc98e 00000000 fffff80e 00000000 ffffb780`b7eee694 ffffc98e ffa00000 ffffb780 b7eee710 ffffb780`b7eee6a4 ffffb780 00000000 00000000 c7477260 ffffb780`b7eee6b4 ffffc98e b7eee7a0 ffffb780 b7eee6f0 ffffb780`b7eee6c4 ffffb780 e04959ca fffff80e 00000000 ffffb780`b7eee6d4 00000000 00000028 00000000 00000002Du kan visa de första fyra byteen av en adress genom att ange intervallparametern L4.
kd> dd ffffb780`b7eee664 l4 ffffb780`b7eee664 ffa00000 00000018 00000000 c52d7008För att se de olika typerna av minnesutdata som visas, skriv kommandona du, da och db.
kd> du ffffb780`b7eee664 ffffb780`b7eee664 "" kd> a ffffb780`b7eee664 ffffb780`b7eee664 "" kd> db 0xffffae015ff97664 ffffae01`5ff97664 00 80 bc ff 18 00 00 00-00 00 00 00 08 50 e0 51 .............P.Q ffffae01`5ff97674 00 c0 ff ff 56 57 da 56-0e f8 ff ff 08 50 e0 51 ....VW.V.....P.Q ffffae01`5ff97684 00 c0 ff ff 00 00 00 00-0e f8 ff ff 00 00 00 00 ................ ffffae01`5ff97694 00 c0 ff ff aa 80 bc ff-01 ae ff ff 10 77 f9 5f .............w._ ffffae01`5ff976a4 01 ae ff ff 40 00 00 00-00 e6 ff ff 10 dc 30 55 ....@.........0U ffffae01`5ff976b4 00 c0 ff ff a0 77 f9 5f-01 ae ff ff f0 76 f9 5f .....w._.....v._ ffffae01`5ff976c4 01 ae ff ff ca 59 da 56-0e f8 ff ff 00 00 00 00 .....Y.V........ ffffae01`5ff976d4 00 00 00 00 28 00 00 00-00 00 00 00 02 00 00 00 ....(...........Använd df float-alternativet för att visa data som flyttalsnummer med enkel precision (4 byte).
df ffffb780`b7eee664 ffffb780`b7eee664 -1.#QNAN 3.3631163e-044 0 -2775.002 ffffb780`b7eee674 -1.#QNAN -5.8032637e+019 -1.#QNAN -2775.002 ffffb780`b7eee684 -1.#QNAN 0 -1.#QNAN 0 ffffb780`b7eee694 -1.#QNAN -1.#QNAN -1.#QNAN -2.8479408e-005
Skriva till minne
På samma sätt som de kommandon som används för att läsa minne kan du använda e*-kommandona för att ändra minnesinnehållet.
| Befallning | Beskrivning |
|---|---|
st |
ASCII-sträng (inte NULL-avslutad) |
EU |
Unicode-sträng (inte NULL-avslutad |
Ew |
Word-värden (2 byte) |
eza |
NULL-avslutad ASCII-sträng |
ezu |
NULL-avslutad Unicode-sträng |
eb |
Bytevärden |
Ed |
Dubbla ordvärden (4 byte) |
I följande exempel visas hur du skriver över minnet.
Leta först upp adressen till den lVolume som används i exempelkoden.
kd> ? lVolume Evaluate expression: -79711507126684 = ffffb780`b7eee664Skriv över minnesadressen med nya tecken med hjälp av eb-kommandot .
kd> eb 0xffffb780`b7eee664 11 11 11 11 11Visa minnesplatsen för att bekräfta att tecknen har skrivits över genom att skriva db-kommandot .
kd> db 0xffffb780`b7eee664 ffffb780`b7eee664 11 11 11 11 11 00 00 00-00 00 00 00 08 70 2d c5 .............p-. ffffb780`b7eee674 8e c9 ff ff 56 57 49 e0-0e f8 ff ff 08 70 2d c5 ....VWI......p-. ffffb780`b7eee684 8e c9 ff ff 00 00 00 00-0e f8 ff ff 00 00 00 00 ................ ffffb780`b7eee694 8e c9 ff ff 00 00 a0 ff-80 b7 ff ff 10 e7 ee b7 ................ ffffb780`b7eee6a4 80 b7 ff ff 00 00 00 00-00 00 00 00 60 72 47 c7 ............`rG. ffffb780`b7eee6b4 8e c9 ff ff a0 e7 ee b7-80 b7 ff ff f0 e6 ee b7 ................ ffffb780`b7eee6c4 80 b7 ff ff ca 59 49 e0-0e f8 ff ff 00 00 00 00 .....YI......... ffffb780`b7eee6d4 00 00 00 00 28 00 00 00-00 00 00 00 02 00 00 00 ....(...........
Du kan också ändra innehållet i minnet i ett klock- eller lokalfönster. För klockfönstret kan du se variabler som inte hör till den aktuella ramen. Det är inte relevant att ändra dem om de inte finns i kontexten.
Avsnitt 13: Avsluta WinDbg-sessionen
<-På värdsystemet
Om du vill lämna felsökningsprogrammet kopplat, men vill arbeta med målet, rensa eventuella brytpunkter med bc *, så att måldatorn inte försöker ansluta till värddatorns felsökningsprogram. Använd sedan kommandot g för att låta måldatorn köras igen.
Avsluta felsökningssessionen genom att bryta dig in i felsökningsprogrammet i värdsystemet och ange kommandot qd (Avsluta och Koppla från) eller välj Sluta felsöka på menyn.
0: kd> qd
Mer information finns i Avsluta en felsökningssession i WinDbg (klassisk) i felsökningsreferensdokumentationen.
Avsnitt 14: Windows-felsökningsresurser
Ytterligare information finns i Windows-felsökning. Observera att vissa av dessa böcker kommer att använda äldre versioner av Windows, till exempel Windows Vista i sina exempel, men de begrepp som beskrivs gäller för de flesta versioner av Windows.
Böcker
Avancerad Windows-felsökning av Mario Hewardt och Daniel Pravat
Inne i Windows Debugging: En praktisk guide till felsöknings- och spårningsstrategier i Windows® av Tarik Soulami
Windows Internals av Pavel Yosifovich, Alex Ionescu, Mark Russinovich och David Solomon
Video
Defrag Tools Show WinDbg Avsnitt 13-29: </shows/defrag-tools/>
Utbildningsleverantörer:
OSR – https://www.osr.com/