Dela via


Felsöka drivrutiner – Steg för steg-laboration (Sysvad-kärnläge)

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:

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.

Diagram som visar två datorer som är anslutna via en nätverkshubb/router.

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

  1. Ö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 . . . . . . . . . :
  1. Registrera IP-adressen för värdsystemet: ______________________________________

  2. Registrera värdsystemets värdnamn: ______________________________________

–> I målsystemet

  1. Ö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.

  1. 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.

  1. 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

  2. Ö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
  1. 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.

  1. 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.

Skärmbild av Windows Säkerhetsavisering som anger att Windows-brandväggen har blockerat vissa funktioner i en app.

<– På värdsystemet

  1. Ö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 
  1. 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.

Skärmbild av Windows Debugger som visar kommandofönsterutdata från en live-kernelanslutning.

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.

  1. 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.
  2. 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 .

  1. 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 .

Skärmbild av felsökningshjälpprogrammet som visar hjälp för kommandot .prefer-dml.

Visa windowsversionen i målsystemet

  1. 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

  1. 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.

  1. 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

    Skärmbild av GitHub-lagringsplatsen som visar den allmänna mappen och knappen Ladda ned ZIP.

    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

  2. Ö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.

    Skärmbild av Visual Studio med adapter.cpp fil som lästs in från Sysvad-projektet.

  3. 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.

  4. Kontrollera drivrutinssignering

    Leta upp TabletAudioSample. Öppna Sysvad-drivrutinens egenskapssida och kontrollera att signeringsläget är inställt på >.

  5. 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.

  6. 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.

  1. 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.
  2. 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.

  1. Aktivera testsignerade drivrutiner

    Så här aktiverar du möjligheten att köra testsignerade drivrutiner:

    1. Öppna Windows-inställningar.

    2. I Update and Securityväljer du Recovery.

    3. Under Avancerad startväljer du Starta om nu.

    4. När datorn startas om väljer du Felsök.

    5. Välj sedan Avancerade alternativ, Startinställningar och välj sedan Starta om.

    6. Välj Inaktivera tvingande av drivrutinssignatur genom att trycka på F7-tangenten .

    7. Datorn börjar med de nya värdena på plats.

  2. –> 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.

    Skärmbild av Windows-säkerhetsvarning som anger att Windows inte kan verifiera utgivaren.

    Tips/Råd

     Om du har problem med installationen kontrollerar du följande fil för mer information. %windir%\inf\setupapi.dev.log

    Mer 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_TabletAudioSample

  3. Granska 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.

    Skärmbild av Device Manager-trädet med exempel på virtuell ljudenhetstablett markerat.

    När du har installerat exempeldrivrutinen är du nu redo att testa den.

Testa ljuddrivrutinen Sysvad

  1. 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.

  2. Ö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.

  3. 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

  1. 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.1sp3yo9yz874p
    
  2. Använd Ctrl+Break (Rullningslås) för att bryta sig in i koden som körs i målsystemet.

Ange symbolsökvägen

  1. Om du vill ange symbolsökvägen till Microsoft-symbolservern i WinDbg-miljön använder du kommandot .symfix .

    0: kd> .symfix
    
  2. Om 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 /f
    

    Observera 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

  1. 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.

  2. 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.

  3. 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).

  4. 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.pdb
    
  5. Anvä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

  1. 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…
    ...
    
  2. Använd Ctrl+F för att söka i utdata som genereras för att leta efter namnet på enhetsdrivrutinen sysvad.

    Hitta dialogrutan med termen

    En post för enhetsnod med namnet sysvad_TabletAudioSample kommer 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.

  3. !devnode 0 1 sysvad_TabletAudioSample Anvä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)
    
  4. 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.
    
  5. 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!PnpHandler
    
  6. Ange > 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.

Diagram över ett enhetsnodträd som består av cirka 20 noder.

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).

  1. Använd WinDbg-användargränssnittet för att bekräfta att Debug>Source Mode är aktiverat i den aktuella WinDbg-sessionen.

  2. Lägg till din lokala kodplats i källsökvägen genom att skriva följande kommando.

    .sympath+ C:\WDK_Samples\Sysvad
    
  3. Lägg till din lokala symbolplats i symbolsökvägen genom att skriva följande kommando.

    .sympath+ C:\WDK_Samples\Sysvad
    
  4. Ange 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 0xFFFFFFFF
    
  5. Ange 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.

  6. 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!AddDevice
    
  7. Starta om kodkörningen i målsystemet genom att skriva go-kommandot g.

  8. ->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.

  9. Välj och håll (eller högerklicka) posten för den virtuella ljuddrivrutinen igen och välj Aktivera på menyn.

  10. <– 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],rdx
    

    Om 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;
    } // AddDevice
    
  11. Stega 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.

  12. 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.

  1. <– 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.

  2. Rensa de tidigare brytpunkterna med bc *.

  3. 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"
    
  4. 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::MixerVolumeWrite
    
  5. Starta om kodkörningen i målsystemet genom att skriva go-kommandot g.

  6. 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.

  7. 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],r9d
    

    Du bör stanna vid den här raden i common.cpp

    {
        if (m_pHW)
        {
            m_pHW->SetMixerVolume(Index, Channel, Value);
        }
    } // MixerVolumeWrite
    
  8. Anvä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 = 0n24
    
  9. Tryck F10 för att enkelt stega igenom koden.

  10. 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+t Kommandot 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.

  1. 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;
    } // AddDevice
    
  2. Fö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.

  3. Rensa eventuella tidigare brytpunkter och kontrollera att felsökningsprogrammet är kopplat till måldatorn.

  4. 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.

  1. Använd dv-kommandot för att undersöka regionvariablerna som är associerade med tabletaudiosample!CMiniportWaveRT::New*.

    kd> dv tabletaudiosample!CMiniportWaveRT::New*
    
  2. Rensa föregående brytpunkter

    bc *
    
  3. 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"
    
  4. Starta om kodkörningen i målsystemet genom att skriva go-kommandot g.

  5. –> 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.

  6. <– 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],r9d
    

    Kä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.
    
    --*/
    {
    
    ...
    
  7. 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`00000200
    
  8. Anvä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]              : 0xff
    
  9. Globala variabler

    Du hittar minnesplatsen för en global variabel genom att skriva ? <variabelnamn>.

    0: kd> ? signalProcessingMode
    Evaluate expression: -52768896396472 = ffffd001`c8acd348
    
  10. Detta 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 ffffe000
    
  11. Du 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 ffffe000
    
  12. Visa 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.

    WinDbg-gränssnittet visar lokala exempelkod och kommandofönster.

  13. 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);
        }
    
    ...
    
  14. 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.

WinDbg-gränssnittet som visar anropsstackfönstret.

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.

  • !process Anvä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:

Trådar och processer

Ändra kontexter

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.

Skärmbild av WinDbg-fönstret som visar cirka 12 register.

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.

Skärmbild av fönstret WinDbg disassembly som visar kod för sammansättningsspråk.

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.

Skärmbild av WinDbg-visningsminnesfönstret med olika alternativ för visningsformat.

  1. 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 *
    
  2. 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"
    
  3. Ange brytpunkterna för att bekräfta att brytpunkten har angetts korrekt.

    kd> bl
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  4. 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],r9d
    
  5. Använd menyalternativet Visa>lokal om du vill visa lokala variabler. Observera det aktuella värdet för variabeln IVolume.

  6. 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-6291456
    
  7. Brytpunkten 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;
    }
    
  8. 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
    0n0
    

    Eftersom variabeln ännu inte har definierats innehåller den inte information.

  9. Tryck på F10 för att köra framåt till den sista kodraden i SetDeviceChannelVolume.

        return ntStatus;
    
  10. Visa värdet på minnesplatsen för IVolume med hjälp av kommandot dt (visningstyp).

    kd> dt lVolume
    Local var @ 0xffffb780b7eee664 Type long
    0n-6291456
    

    Nu när variabeln är aktiv visas värdet 6291456 i det här exemplet.

  11. Du kan också visa minnesplatsen för IVolume med hjälp av ? (Utvärdera uttryck) befallning.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  12. Adressen 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 00000002
    
  13. Du 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 c52d7008
    
  14. Fö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.

  1. Leta först upp adressen till den lVolume som används i exempelkoden.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  2. Skriv över minnesadressen med nya tecken med hjälp av eb-kommandot .

    kd> eb 0xffffb780`b7eee664 11 11 11 11 11
    
  3. Visa 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/

Se även

Komma igång med Windows-felsökning