Delen via


Fouten opsporen in stuurprogramma's - Stapsgewijze testomgeving (Sysvad-kernelmodus)

Dit lab biedt praktijkoefeningen die laten zien hoe u fouten kunt opsporen in het apparaatstuurprogramma van de Sysvad-audiokernelmodus.

Microsoft Windows Debugger (WinDbg) is een krachtig windows-hulpprogramma voor foutopsporing dat u kunt gebruiken om foutopsporing in de gebruikersmodus en kernelmodus uit te voeren. WinDbg biedt foutopsporing op bronniveau voor de Windows-kernel, kernelmodusstuurprogramma's en systeemservices, evenals toepassingen en stuurprogramma's in de gebruikersmodus.

WinDbg kan stapsgewijs door de broncode bladeren, onderbrekingspunten instellen, variabelen weergeven (inclusief C++-objecten), stacktraceringen en geheugen. Met het Foutopsporingsprogramma-opdrachtvenster kan de gebruiker een groot aantal opdrachten uitvoeren.

Labconfiguratie

U hebt de volgende hardware nodig om het lab te kunnen voltooien:

  • Een laptop of desktopcomputer (host) met Windows 10
  • Een laptop of desktopcomputer (doel) met Windows 10
  • Een netwerkhub/router en netwerkkabels om de twee pc's te verbinden
  • Toegang tot internet om symboolbestanden te downloaden

U hebt de volgende software nodig om het lab te kunnen voltooien.

  • Microsoft Visual Studio 2017
  • Windows Software Development Kit (SDK) voor Windows 10
  • Windows Driver Kit (WDK) voor Windows 10
  • Het sysvad-voorbeeldaudiostuurprogramma voor Windows 10

Zie De Windows Driver Kit (WDK) downloaden voor meer informatie over het downloaden en installeren van de WDK.

Stapsgewijze instructies voor sysvad-foutopsporing

Dit lab begeleidt u bij het opsporen van fouten in een kernelmodusstuurprogramma. In de oefeningen wordt het voorbeeld van het virtuele audiostuurprogramma Syvad gebruikt. Omdat het Syvad-audiostuurprogramma niet communiceert met werkelijke audiohardware, kan het op de meeste apparaten worden gebruikt. In het lab worden de volgende taken behandeld:

Lab voor echostuurprogramma's

Het Echo-stuurprogramma is een eenvoudiger stuurprogramma dan het Sysvad-audiostuurprogramma. Als u nieuw bent met WinDbg, overweeg dan om eerst het Debuggen van universele stuurprogramma's - stapsgewijze instructielab (Echo in kernelmodus) te voltooien. In dit lab worden de installatierichtingen van dat lab opnieuw gebruikt. Als u dat lab hebt voltooid, kunt u secties 1 en 2 hier overslaan.

Sectie 1: Verbinding maken met een WinDbg-sessie in de kernelmodus

In sectie 1 configureert u netwerkopsporing op de host en het doelsysteem.

De pc's in dit lab moeten worden geconfigureerd voor het gebruik van een Ethernet-netwerkverbinding voor kernelfoutopsporing.

In dit lab worden twee computers gebruikt. WinDbg wordt uitgevoerd op het hostsysteem en het Sysvad-stuurprogramma wordt uitgevoerd op het doelsysteem .

Gebruik een netwerkhub/router en netwerkkabels om de twee pc's te verbinden.

Diagram met twee pc's die zijn verbonden via een netwerkhub/router.

Als u wilt werken met kernelmodustoepassingen en WinDbg wilt gebruiken, raden we u aan het KDNET over Ethernet-transport te gebruiken. Zie Aan de slag met WinDbg (Kernel-Mode) voor meer informatie over het gebruik van het Ethernet-transportprotocol. Zie Een computer voorbereiden voor handmatige implementatie van stuurprogramma's en het automatisch instellen van KDNET-netwerk kernelfoutopsporing voor meer informatie over het instellen van de doelcomputer.

Kernelmodus-debugging configureren via Ethernet

Voer de volgende stappen uit om foutopsporing in de kernelmodus in te schakelen op het doelsysteem.

<- Op het hostsysteem

  1. Open een opdrachtprompt op het hostsysteem en typ ipconfig /all om het IP-adres te bepalen.
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. Noteer het IP-adres van het hostsysteem: ______________________________________

  2. Noteer de hostnaam van het hostsysteem: ______________________________________

-> Op het doelsysteem

  1. Open een opdrachtprompt op het doelsysteem en gebruik de ping-opdracht om de netwerkverbinding tussen de twee systemen te bevestigen. Gebruik het werkelijke IP-adres van het hostsysteem dat u hebt vastgelegd in plaats van 169.182.1.1 die wordt weergegeven in de voorbeelduitvoer.
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

Voer de volgende stappen uit om het hulpprogramma KDNET te gebruiken om foutopsporing in de kernelmodus op het doelsysteem in te schakelen.

  1. Zoek op het hostsysteem de WDK KDNET-map. Standaard bevindt het zich hier.

    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64

In deze labs wordt ervan uitgegaan dat beide pc's een 64-bits versie van Windows uitvoeren op zowel het doel als de host. Als dat niet het geval is, is de beste methode om de tools in dezelfde bit-versie op de host te gebruiken als waarin het doel draait. Als het doel bijvoorbeeld 32-bits Windows gebruikt, voert u een 32-versie van het foutopsporingsprogramma uit op de host. Zie De 32-bits of 64-bits hulpprogramma's voor foutopsporing kiezen voor meer informatie.

  1. Zoek deze twee bestanden op en kopieer ze naar een netwerkstation of USB-stick, zodat ze beschikbaar zijn op de doelcomputer.

    kdnet.exe

    VerifiedNICList.xml

  2. Open op de doelcomputer een opdrachtpromptvenster als administrator. Voer deze opdracht in om te controleren of de NIC op de doel-pc wordt ondersteund.

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. Typ deze opdracht om het IP-adres van het hostsysteem in te stellen. Gebruik het werkelijke IP-adres van het hostsysteem dat u hebt vastgelegd in plaats van 169.182.1.1 die wordt weergegeven in de voorbeelduitvoer. Kies een uniek poortadres voor elk doel-/hostpaar waarmee u werkt, zoals 50010.
C:\>kdnet 169.182.1.1 50010

Enabling network debugging on Intel(R) 82577LM Gigabit Network Connection.
Key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p

Belangrijk

Voordat u BCDEdit gebruikt om opstartgegevens te wijzigen, moet u mogelijk de Windows-beveiligingsfuncties, zoals BitLocker en Beveiligd opstarten, tijdelijk onderbreken op de test-pc. Schakel deze beveiligingsfuncties opnieuw in wanneer het testen is voltooid en de test-pc op de juiste wijze beheert wanneer de beveiligingsfuncties zijn uitgeschakeld. Beveiligd opstarten is doorgaans uitgeschakeld in UEFI. Voor toegang tot de UEFI-instelling gebruikt u Systeem, Herstel, Geavanceerd opstarten. Bij opnieuw opstarten selecteert u Problemen oplossen, Geavanceerde opties, UEFI-firmware-instellingen. Wees voorzichtig, omdat uEFI-opties onjuist instelt of BitLocker uitschakelt, kan het systeem onbruikbaar zijn.

  1. Typ deze opdracht om te bevestigen dat de dbgsettings juist zijn ingesteld.
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.

Kopieer de automatisch gegenereerde unieke sleutel naar een tekstbestand om te voorkomen dat u deze op de host-pc moet typen. Kopieer het tekstbestand met de sleutel naar het hostsysteem.

OpmerkingFirewalls en foutopsporingsprogramma's

Als u een pop-upbericht van de firewall ontvangt en u het foutopsporingsprogramma wilt gebruiken, schakelt u alle drie de selectievakjes in.

Schermopname van windows-beveiligingswaarschuwing die aangeeft dat Bepaalde functies van een app zijn geblokkeerd door Windows Firewall.

<- Op het hostsysteem

  1. Open op de hostcomputer een opdrachtpromptvenster als administrator. Ga naar de directory WinDbg.exe. We gebruiken de x64version van WinDbg.exe van de Windows Driver Kit (WDK) die is geïnstalleerd als onderdeel van de installatie van de Windows-kit.
C:\> Cd C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 
  1. Start WinDbg met foutopsporing van externe gebruikers met behulp van de volgende opdracht. De waarde voor de sleutel en poort komt overeen met wat u eerder hebt ingesteld met BCDEdit op het doel.
C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p

->Op het doelsysteem

Start het doelsysteem opnieuw op.

<-Op het hostsysteem

Binnen een paar minuten moet de uitvoer voor foutopsporing worden weergegeven op het hostsysteem.

Schermopname van Windows Debugger met opdrachtvensteruitvoer van een live kernelverbinding.

Het Foutopsporingsopdrachtvenster is het primaire foutopsporingsinformatievenster in WinDbg. U kunt opdrachten voor foutopsporingsprogramma's invoeren en de uitvoer van de opdracht in dit venster weergeven.

Het venster van de foutopsporingsopdracht is verdeeld in twee deelvensters. U typt opdrachten in het kleinere deelvenster (het opdrachtinvoervenster) onderaan het venster en bekijkt de uitvoer van de opdracht in het grotere deelvenster boven aan het venster.

Gebruik in het opdrachtinvoervenster de pijl-omhoog en pijl-omlaag om door de opdrachtgeschiedenis te bladeren. Wanneer een opdracht wordt weergegeven, kunt u deze bewerken of op Enter drukken om de opdracht uit te voeren.

Sectie 2: foutopsporingsopdrachten en -technieken in kernelmodus

In sectie 2 gebruikt u foutopsporingsopdrachten om informatie over het doelsysteem weer te geven.

<- Op het hostsysteem

DML (Debugger Markup Language) inschakelen met .prefer_dml

Sommige foutopsporingsopdrachten geven tekst weer met behulp van Debugger Markup Language die u kunt selecteren om snel meer informatie te verzamelen.

  1. Gebruik Ctrl+Break (Scroll Lock) in WinDBg om in te breken in de code die wordt uitgevoerd op het doelsysteem. Het kan even duren voordat het doelsysteem reageert.
  2. Voer de volgende opdracht in om DML in te schakelen in het Debug-opdrachtvenster.
0: kd> .prefer_dml 1
DML versions of commands on by default

.hh gebruiken om hulp te krijgen

U kunt toegang krijgen tot de opdrachtreferentiehelp met behulp van de opdracht .hh.

  1. Typ de volgende opdracht om het commando-overzicht voor .prefer_dml weer te geven.
    0: kd> .hh .prefer_dml
    

Het Help-bestand voor foutopsporingsprogramma geeft help weer voor de opdracht .prefer_dml .

Schermopname van Debugger Help-toepassing met help voor de opdracht .prefer-dml.

De versie van Windows weergeven op het doelsysteem

  1. Gedetailleerde versie-informatie weergeven op het doelsysteem door de opdracht vertarget (Doelcomputerversie weergeven) in het WinDbg-venster te typen.
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

De geladen modules weergeven

  1. U kunt controleren of u met het juiste kernelmodusproces werkt door de geladen modules weer te geven door de opdracht LM (List Loaded Modules) in het WinDbg-venster te typen.
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
...

Notitie Uitvoer die is weggelaten, wordt aangegeven met '... " in dit lab.

Omdat we het symboolpad en de geladen symbolen nog moeten instellen, is er beperkte informatie beschikbaar in het foutopsporingsprogramma.

Sectie 3: Het Sysvad-audiostuurprogramma downloaden en bouwen

In sectie 3 downloadt en bouwt u het Sysvad-audiostuurprogramma.

Normaal gesproken werkt u met uw eigen stuurprogrammacode wanneer u WinDbg gebruikt. Om vertrouwd te raken met het opsporen van fouten in audiostuurprogramma's, wordt het Sysvad virtuele audiostuurprogramma gebruikt. Dit voorbeeld wordt gebruikt om te illustreren hoe u één stap door systeemeigen kernelmoduscode kunt uitvoeren. Deze techniek kan zeer waardevol zijn voor het opsporen van fouten in complexe kernelmoduscodeproblemen.

Voer de volgende stappen uit om het sysvad-voorbeeldaudiostuurprogramma te downloaden en te bouwen.

  1. Het Sysvad-audiovoorbeeld downloaden en extraheren uit GitHub

    U kunt een browser gebruiken om het Sysvad-voorbeeld en Readme.md bestand hier weer te geven:

    https://github.com/Microsoft/Windows-driver-samples/tree/main/audio/sysvad

    Schermopname van de GitHub-opslagplaats met de algemene map en de knop ZIP downloaden.

    In dit lab ziet u hoe u de universele stuurprogrammavoorbeelden in één zip-bestand kunt downloaden.

    een. Download het master.zip-bestand naar uw lokale harde schijf.

    https://github.com/Microsoft/Windows-driver-samples/archive/master.zip

    b. Selecteer en houd Windows-driver-samples-master.zip vast (of klik met de rechtermuisknop) en kies Alles uitpakken. Geef een nieuwe map op of blader naar een bestaande map waarin de geëxtraheerde bestanden worden opgeslagen. U kunt bijvoorbeeld C:\WDK_Samples\ opgeven als de nieuwe map waarin de bestanden worden geëxtraheerd.

    Hoofdstuk c. Nadat de bestanden zijn uitgepakt, gaat u naar de volgende submap.

    C:\WDK_Samples\Sysvad

  2. De stuurprogrammaoplossing openen in Visual Studio

    Selecteer in Visual Studio File>Open>Project/Solution... en navigeer naar de map met de geëxtraheerde bestanden (bijvoorbeeld C:\WDK_Samples\Sysvad). Dubbelklik op het Syvad-oplossingsbestand .

    Zoek in Visual Studio de Solution Explorer. (Als dit nog niet is geopend, kiest u Solution Explorer in het menu Beeld .) In Solution Explorer ziet u één oplossing met een aantal projecten.

    Schermopname van Visual Studio met het adapter.cpp-bestand dat is geladen vanuit het Sysvad-project.

  3. De configuratie en het platform van het voorbeeld instellen

    Selecteer in Solution Explorer de oplossing sysvad (7 van 7 projecten) en houd deze vast (of klik erop met de rechtermuisknop) en kies Configuration Manager. Zorg ervoor dat de configuratie- en platforminstellingen hetzelfde zijn voor de vier projecten. De configuratie is standaard ingesteld op 'Win10 Debug' en het platform is ingesteld op 'Win64' voor alle projecten. Als u configuratie- en/of platformwijzigingen voor één project aanbrengt, moet u dezelfde wijzigingen aanbrengen voor de resterende drie projecten.

    Notitie In dit lab wordt ervan uitgegaan dat 64-bits Windows wordt gebruikt. Als u 32-bits Windows gebruikt, bouwt u het stuurprogramma voor 32-bits.

  4. Driverondertekening controleren

    Zoek de TabletAudioSample. Open de eigenschappenpagina van het Sysvad-stuurprogramma en zorg ervoordat > deondertekeningsmodus voor stuurprogramma's is ingesteld op Test Sign.

  5. Stuurprogramma-voorbeelden moeten worden gewijzigd om waarden te gebruiken die niet overlappen met bestaande stuurprogramma's. Raadpleeg Van voorbeeldcode naar productiestuurprogramma: wat u kunt wijzigen in de voorbeelden over het maken van een uniek stuurprogrammavoorbeeld dat naast bestaande echte stuurprogramma's in Windows wordt geïnstalleerd.

  6. Het voorbeeld bouwen met Visual Studio

    Selecteer in Visual Studio Builden>Oplossing Bouwen.

    In de buildvensters moet een bericht worden weergegeven dat de build voor alle zes projecten is geslaagd.

Hint

Als er een buildfout wordt weergegeven, gebruikt u het buildfoutnummer om een oplossing te bepalen. Bijvoorbeeld, MSBuild-fout MSB8040 beschrijft hoe te werken met spectre-beveiligde bibliotheken.

  1. De ingebouwde stuurprogrammabestanden zoeken

    Navigeer in Verkenner naar de map die de uitgepakte bestanden voor het voorbeeld bevat. U navigeert bijvoorbeeld naar C:\WDK_Samples\Sysvad, als dat de map is die u eerder hebt opgegeven. Binnen die map is de locatie van de gecompileerde stuurprogrammabestanden afhankelijk van de configuratie- en platforminstellingen die u in Configuration Manager hebt geselecteerd. Als u bijvoorbeeld de standaardinstellingen ongewijzigd hebt gelaten, worden de gecompileerde stuurprogrammabestanden opgeslagen in een map met de naam \x64\Debug voor een 64-bits, foutopsporingsbuild.

    Navigeer naar de map met de ingebouwde bestanden voor het TabletAudioSample-stuurprogramma:

    C:\WDK_Samples\Sysvad\TabletAudioSample\x64\Debug. De map bevat het stuurprogramma TabletAudioSample .SYS, het pdp-symboolbestand en het inf-bestand. U moet ook de dll's en symboolbestanden van DelayAPO, KWSApo en KeywordDetectorContosoAdapter vinden.

    Als u het stuurprogramma wilt installeren, hebt u de volgende bestanden nodig.

    Bestandsnaam Beschrijving
    TabletAudioSample.sys Het stuurprogrammabestand.
    TabletAudioSample.pdb Het stuurprogrammasymboolbestand.
    tabletaudiosample.inf Een informatiebestand (INF) dat informatie bevat die nodig is om het stuurprogramma te installeren.
    KeywordDetectorContosoAdapter.dll Een voorbeeld van een trefwoorddetector.
    KeywordDetectorContosoAdapter.pdb Het voorbeeldbestand met trefwoorddetectorsymbolen.
    DelayAPO.dll Een voorbeeldvertraging APO.
    DelayAPO.pdb Het vertraagde APO-symboolbestand.
    KWSApo.dll Een voorbeeld van een trefwoordspotter APO.
    KWSApo.pdb Het symboolbestand voor trefwoordspotters.
    TabletAudioSample.cer Het TabletAudioSample-certificaatbestand.
  2. Zoek een USB-duimstation of stel een netwerkshare in om de ingebouwde stuurprogrammabestanden van de host naar het doelsysteem te kopiëren.

In de volgende sectie kopieert u de code naar het doelsysteem en installeert en test u het stuurprogramma.

Sectie 4: Het sysvad-audiostuurprogrammavoorbeeld installeren op het doelsysteem

In sectie 4 gebruikt u devcon om het Sysvad-audiostuurprogramma te installeren.

-> Op het doelsysteem

De computer waarop u het stuurprogramma installeert, wordt de doelcomputer of de testcomputergenoemd. Dit is doorgaans een afzonderlijke computer van de computer waarop u het stuurprogrammapakket ontwikkelt en bouwt. De computer waarop u het stuurprogramma ontwikkelt en bouwt, wordt de hostcomputergenoemd.

Het proces voor het verplaatsen van het stuurprogrammapakket naar de doelcomputer en het installeren van het stuurprogramma wordt het implementeren van het stuurprogramma genoemd.

Voordat u een stuurprogramma implementeert, moet u de doelcomputer voorbereiden door testondertekening in te schakelen. Daarna bent u klaar om het ingebouwde stuurprogrammavoorbeeld uit te voeren op het doelsysteem.

Voer de volgende stappen uit om het stuurprogramma op het doelsysteem te installeren.

  1. Testondertekende stuurprogramma's inschakelen

    Als u de mogelijkheid wilt inschakelen om ondertekende stuurprogramma's te testen:

    1. Open Windows-instellingen.

    2. Selecteer Herstelin Update en Beveiliging.

    3. Onder Geavanceerde opstart, selecteer Nu opnieuw opstarten.

    4. Wanneer de pc opnieuw wordt opgestart, selecteert u Problemen oplossen.

    5. Selecteer vervolgens Geavanceerde opties, Opstartinstellingen en selecteer Vervolgens Opnieuw opstarten.

    6. Selecteer de optie Uitschakeling van het afdwingen van stuurprogrammahandtekeningen door op de F7-toets te drukken.

    7. De pc begint met de nieuwe waarden.

  2. -> Op het doelsysteem

    Het stuurprogramma installeren

    In de volgende instructies ziet u hoe u het voorbeeldstuurprogramma installeert en test.

    Het INF-bestand dat is vereist voor het installeren van dit stuurprogramma, is TabletAudioSample.inf. Open op de doelcomputer een opdrachtpromptvenster als administrator. Navigeer naar de map van het stuurprogrammapakket, klik met de rechtermuisknop op het bestand TabletAudioSample.inf en selecteer Installeren.

    Er wordt een dialoogvenster weergegeven dat aangeeft dat het teststuurprogramma een niet-ondertekend stuurprogramma is. Selecteer Dit stuurprogramma toch installeren om door te gaan.

    Schermopname van windows-beveiligingswaarschuwing waarin wordt aangegeven dat Windows de uitgever niet kan verifiëren.

    Hint

     Als u problemen ondervindt met de installatie, controleert u het volgende bestand voor meer informatie. %windir%\inf\setupapi.dev.log

    Zie Een computer configureren voor implementatie, testen en foutopsporing voor meer gedetailleerde instructies.

    Het INF-bestand bevat de hardware-id voor het installeren van de tabletaudiosample.sys. Voor het Syvad-voorbeeld is de hardware-id: root\sysvad_TabletAudioSample

  3. Het stuurprogramma controleren in Apparaatbeheer

    Voer op de doelcomputer in een opdrachtpromptvenster devmgmt- in om Apparaatbeheer te openen. Selecteer in Apparaatbeheer in het menu Beeld de optie Apparaten op type.

    Zoek in de apparaatstructuur naar Virtual Audio Device (WDM) - Tablet Sample in het knooppunt Audioapparaat. Dit bevindt zich doorgaans onder het knooppunt Geluids-, video- en gamecontrollers . Controleer of deze is geïnstalleerd en actief is.

    Markeer het stuurprogramma voor de werkelijke hardware op de pc in Apparaatbeheer. Selecteer en houd het stuurprogramma ingedrukt (of klik er met de rechtermuisknop op) en selecteer uitschakelen om het stuurprogramma uit te schakelen.

    Bevestig in Apparaatbeheer dat het audiohardwarestuurprogramma de pijl-omlaag weergeeft, waarmee wordt aangegeven dat deze is uitgeschakeld.

    Schermopname van de Apparaatbeheer-structuur met het Virtueel audioapparaat Tabletvoorbeeld gemarkeerd.

    Nadat het voorbeeldstuurprogramma is geïnstalleerd, kunt u het testen.

Het Sysvad-audiostuurprogramma testen

  1. Voer op de doelcomputer in een opdrachtpromptvenster devmgmt- in om Apparaatbeheer te openen. Selecteer in Apparaatbeheer in het menu Beeld de optie Apparaten op type. Zoek in de apparaatstructuur naar Virtual Audio Device (WDM) - Tablet Sample.

  2. Open het Configuratiescherm en navigeer naar Hardware en Geluid>Audioapparaten beheren. Selecteer in het dialoogvenster Geluid het luidsprekerpictogram met het label Virtual Audio Device (WDM) - Tablet Sample en selecteer Vervolgens Standaard instellen, maar selecteer OK niet. Hierdoor blijft het dialoogvenster Geluid geopend.

  3. Zoek een MP3- of ander audiobestand op de doelcomputer en dubbelklik erop om het af te spelen. Controleer vervolgens in het dialoogvenster Geluid of er activiteit is in de volumeniveauindicator die is gekoppeld aan het stuurprogramma Virtual Audio Device (WDM) - Tablet Sample .

Sectie 5: WinDbg gebruiken om informatie over het stuurprogramma weer te geven

In sectie 5 stelt u het symboolpad in en gebruikt u opdrachten voor kernelfoutopsporingsprogramma's om informatie weer te geven over het sysvad-voorbeeldstuurprogramma.

Met symbolen kan WinDbg aanvullende informatie weergeven, zoals namen van variabelen, die waardevol kunnen zijn bij het opsporen van fouten. WinDbg maakt gebruik van de foutopsporingssymboolindelingen van Microsoft Visual Studio voor foutopsporing op bronniveau. Het heeft toegang tot elk symbool of elke variabele vanuit een module met PDB-symboolbestanden.

Voer de volgende stappen uit om het foutopsporingsprogramma te laden.

<-Op het hostsysteem

  1. Als u het foutopsporingsprogramma hebt gesloten, opent u het opnieuw met behulp van de volgende opdracht in het opdrachtpromptvenster van de beheerder. Vervang de sleutel en poort door wat u eerder hebt geconfigureerd.

    C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  2. Gebruik Ctrl+Break (Scroll Lock) om in te breken in de code die wordt uitgevoerd op het doelsysteem.

Het symboolpad instellen

  1. Gebruik de opdracht .symfix om het pad naar de Microsoft-symboolserver in te stellen in de WinDbg-omgeving.

    0: kd> .symfix
    
  2. Voeg uw lokale symboollocatie toe om uw lokale symbolen te gebruiken door het pad toe te voegen met .sympath+ en vervolgens .reload /f.

    0: kd> .sympath+ C:\WDK_Samples\Sysvad
    0: kd> .reload /f
    

    Notitie Met de opdracht .reload met de optie /f force verwijdert u alle symboolgegevens voor de opgegeven module en laadt u de symbolen opnieuw. In sommige gevallen wordt met deze opdracht ook de module zelf opnieuw geladen of verwijderd.

Notitie U moet de juiste symbolen laden om geavanceerde functionaliteit te gebruiken die WinDbg biedt. Als u geen symbolen goed hebt geconfigureerd, ontvangt u berichten die aangeven dat symbolen niet beschikbaar zijn wanneer u probeert functionaliteit te gebruiken die afhankelijk is van symbolen.

0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.

Opmerkingsymboolservers

Er zijn een aantal benaderingen die kunnen worden gebruikt om te werken met symbolen. In veel situaties kunt u de pc configureren voor toegang tot symbolen vanaf een symboolserver die Microsoft biedt wanneer ze nodig zijn. In dit scenario wordt ervan uitgegaan dat deze benadering wordt gebruikt. Als de symbolen in uw omgeving zich op een andere locatie bevinden, wijzigt u de stappen om die locatie te gebruiken. Zie Symboolpad voor windows-foutopsporingsprogramma voor meer informatie.

Opmerking: vereisten voor broncodesymbool begrijpen

Als u bronopsporing wilt uitvoeren, moet u een gecontroleerde (foutopsporings) versie van uw binaire bestanden bouwen. De compiler maakt symboolbestanden (.pdb-bestanden). Deze symboolbestanden tonen het foutopsporingsprogramma hoe de binaire instructies overeenkomen met de bronlijnen. De werkelijke bronbestanden zelf moeten ook toegankelijk zijn voor het foutopsporingsprogramma.

De symboolbestanden bevatten niet de tekst van de broncode. Voor foutopsporing is het het beste als de linker uw code niet optimaliseert. Bronopsporing en toegang tot lokale variabelen zijn moeilijker en soms bijna onmogelijk, als de code is geoptimaliseerd. Als u problemen ondervindt bij het weergeven van lokale variabelen of bronlijnen, stelt u de volgende buildopties in.

COMPILE_DEBUG=1 instellen

ENABLE_OPTIMIZER=0 instellen

  1. Typ het volgende in het opdrachtgebied van het foutopsporingsprogramma om informatie weer te geven over het Sysvad-stuurprogramma.

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

    Zie lm voor meer informatie.

  2. Selecteer de koppeling Alle globale symbolen bladeren in de uitvoer van foutopsporing om informatie weer te geven over items symbolen die beginnen met de letter 'a'.

  3. Omdat DML is ingeschakeld, zijn sommige elementen van de uitvoer dynamische koppelingen die u kunt selecteren. Selecteer de gegevenskoppeling in de foutopsporingsuitvoer om informatie te tonen van itemssymbolen die met de letter a beginnen.

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

    Zie x (Symbolen onderzoeken) voor meer informatie.

  4. De extensie !lmi geeft gedetailleerde informatie weer over een module. Typ !lmi tabletaudiosample. De uitvoer moet vergelijkbaar zijn met de tekst die hieronder wordt weergegeven.

    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. Gebruik de extensie !dh om koptekstinformatie weer te geven, zoals hieronder wordt weergegeven.

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

Paragraaf 6: Informatie over plug-and-play-apparaatboom weergeven

In sectie 6 geeft u informatie weer over het sysvad-voorbeeldapparaatstuurprogramma en waar het zich bevindt in de plug- en play-apparaatstructuur.

Informatie over het apparaatstuurprogramma in de plug- en play-apparaatstructuur kan handig zijn voor het oplossen van problemen. Als een apparaatstuurprogramma bijvoorbeeld niet aanwezig is in de apparaatboom, kan er een probleem zijn met de installatie van het apparaatstuurprogramma.

Zie !devnode voor meer informatie over de extensie voor foutopsporing van apparaatknooppunten.

<-Op het hostsysteem

  1. Als u alle apparaatknooppunten in de plug- en play-apparaatstructuur wilt zien, voert u de opdracht !devnode 0 1 in. Het uitvoeren van deze opdracht kan enkele minuten duren. Gedurende die tijd wordt "*Bezet" weergegeven in het statusgebied van 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. Gebruik Ctrl+F om te zoeken in de uitvoer die wordt gegenereerd om te zoeken naar de naam van het apparaatstuurprogramma, sysvad.

    Dialoogvenster Zoeken met de term sysvad die is ingevoerd in het zoekveld.

    Een apparaatknooppuntvermelding met de naam sysvad_TabletAudioSample zal aanwezig zijn in de uitvoer van !devnode voor Syvad.

      DevNode 0xffffe00086e68190 for PDO 0xffffe00089c575a0
        InstancePath is "ROOT\sysvad_TabletAudioSample\0000"
        ServiceName is "sysvad_tabletaudiosample"
        State = DeviceNodeStarted (0x308)
    ...
    

    Houd er rekening mee dat het PDO-adres en het DevNode-adres worden weergegeven.

  3. Gebruik de !devnode 0 1 sysvad_TabletAudioSample opdracht om Plug and Play-informatie weer te geven die is gekoppeld aan het sysvad-apparaatstuurprogramma.

    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. De uitvoer die in de vorige opdracht wordt weergegeven, bevat de PDO die is gekoppeld aan het actieve exemplaar van ons stuurprogramma. In dit voorbeeld is deze 0xffffe00089c575a0. Voer de opdracht !devobj<PDO-adres> in om Plug and Play-informatie weer te geven die is gekoppeld aan het Sysvad-apparaatstuurprogramma. Gebruik het PDO-adres dat !devnode op uw pc weergeeft, niet het adres dat hier wordt weergegeven.

    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. De uitvoer die wordt weergegeven in de opdracht !devobj bevat de naam van het gekoppelde apparaat: \Driver\sysvad_tabletaudiosample. Gebruik de opdracht !drvobj met een bitmasker van 2 om informatie weer te geven die is gekoppeld aan het gekoppelde apparaat.

    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. Voer de opdracht !devstack<PDO-adres> in om Plug en Play-informatie weer te geven die is gekoppeld aan het apparaatstuurprogramma. De uitvoer die wordt weergegeven in de opdracht !devnode 0 1 bevat het PDO-adres dat is gekoppeld aan het actieve exemplaar van ons stuurprogramma. In dit voorbeeld is het 0xffffe00089c575a0. Gebruik het PDO-adres dat !devnode op uw pc weergeeft, niet het adres dat hieronder wordt weergegeven.

    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"
    

De uitvoer laat zien dat we een tamelijk eenvoudige stack voor apparaatstuurprogramma's hebben. Het sysvad_TabletAudioSample-stuurprogramma is een onderliggend element van het PnPManager-knooppunt. De PnPManager is een hoofdknooppunt.

In dit diagram ziet u een complexere apparaatknooppuntboom.

Diagram van een apparaatknooppuntstructuur die bestaat uit ongeveer 20 knooppunten.

Notitie Zie Stuurprogrammastacks en apparaatknooppunten en apparaatstacks voor meer informatie over complexere stuurprogrammastacks.

Sectie 7: Werken met onderbrekingspunten

In sectie 7 werkt u met onderbrekingspunten om de uitvoering van code op specifieke punten te stoppen.

Onderbrekingspunten instellen met behulp van opdrachten

Onderbrekingspunten worden gebruikt om het uitvoeren van code op een bepaalde coderegel te stoppen. Vervolgens kunt u vanaf dat moment verdergaan in de code om fouten op te sporen in die specifieke sectie met code.

Als u een onderbrekingspunt wilt instellen met behulp van een foutopsporingsopdracht, gebruikt u een van de volgende b-opdrachten .

Bp

Hiermee stelt u een onderbrekingspunt in dat actief is totdat de module waarin het zich bevindt wordt ontladen.

Bu

Hiermee stelt u een onderbrekingspunt in dat onopgelost blijft wanneer de module wordt ontladen en opnieuw wordt ingeschakeld wanneer de module opnieuw wordt geladen.

Bm

Hiermee stelt u een onderbrekingspunt in voor een symbool. Met deze opdracht wordt op de juiste wijze gebruikgemaakt van bu of bp en kan jokertekens * worden gebruikt om onderbrekingspunten in te stellen voor alle symbolen die overeenkomen (zoals alle methoden in een klasse).

  1. Gebruik de WinDbg-gebruikersinterface om te bevestigen dat de foutopsporingsbronmodus> is ingeschakeld in de huidige WinDbg-sessie.

  2. Voeg uw lokale codelocatie toe aan het bronpad door de volgende opdracht te typen.

    .sympath+ C:\WDK_Samples\Sysvad
    
  3. Voeg uw lokale symboollocatie toe aan het symboolpad door de volgende opdracht te typen.

    .sympath+ C:\WDK_Samples\Sysvad
    
  4. Het foutopsporingsmasker instellen

    Omdat u met een driver werkt, kan het handig zijn om alle berichten te zien die het kan weergeven. Typ het volgende om het standaardmasker voor foutopsporingsbits te wijzigen, zodat alle foutopsporingsberichten van het doelsysteem worden weergegeven in het foutopsporingsprogramma.

    0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
    
  5. Stel het onderbrekingspunt in met de bm-opdracht met behulp van de naam van het stuurprogramma, gevolgd door de functienaam (AddDevice) waar u het onderbrekingspunt wilt instellen, gescheiden door een uitroepteken.

    0: kd> bm tabletaudiosample!AddDevice
    breakpoint 1 redefined
      1: fffff801`14b5f000 @!"tabletaudiosample!AddDevice"
    

    U kunt verschillende syntaxis gebruiken in combinatie met het instellen van variabelen zoals <module>!<symbool>, <klasse>::<methode>, '<file.cpp>:<regelnummer>', of een bepaald aantal keer een voorwaarde overslaan <#><. Voor meer informatie, zie Onderbrekingspunten gebruiken.

  6. Geef de huidige onderbrekingspunten weer om te bevestigen dat het onderbrekingspunt is ingesteld door de bl-opdracht te typen.

    0: kd> bl
    1 e fffff801`14b5f000     0001 (0001) tabletaudiosample!AddDevice
    
  7. Start de uitvoering van code opnieuw op het doelsysteem door de go-opdracht g te typen.

  8. ->Op het doelsysteem

    Open Apparaatbeheer in Windows met behulp van het pictogram of door mmc devmgmt.msc in te voeren. Vouw in Apparaatbeheer het knooppunt Geluid, video- en gamecontrollers uit. Selecteer en houd de invoer van het virtuele audiostuurprogramma ingedrukt (of klik erop met de rechtermuisknop) en selecteer Uitschakelen in het menu.

  9. Selecteer en houd de vermelding van het virtuele audiostuurprogramma weer ingedrukt (of klik erop met de rechtermuisknop) en selecteer Inschakelen in het menu.

  10. <- Op het hostsysteem

    Dit moet ertoe leiden dat Windows het stuurprogramma opnieuw laadt, waardoor AddDevice wordt aanroepen. Hierdoor wordt het onderbrekingspunt voor foutopsporing van AddDevice geactiveerd en wordt de uitvoering van de stuurprogrammacode op het doelsysteem gestopt.

    Breakpoint 1 hit
    tabletaudiosample!AddDevice:
    fffff801`14baf000 4889542410      mov     qword ptr [rsp+10h],rdx
    

    Als uw bronpad juist is ingesteld, moet u stoppen bij de AddDevice-routine in 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. Voer de regel voor regel door de code door de p-opdracht te typen of op F10 te drukken. U kunt uit de sysvad AddDevice-code stappen naar PpvUtilCall en PnpCallAddDevice, en vervolgens naar de Windows-code PipCallDriverAddDevice. U kunt een getal opgeven voor de p-opdracht om meerdere regels vooruit te gaan, bijvoorbeeld p 5.

  12. Wanneer u klaar bent met het doorlopen van de code, gebruikt u de go-opdracht g om de uitvoering op het doelsysteem opnieuw te starten.

Onderbrekingspunten voor geheugentoegang instellen

U kunt ook onderbrekingspunten instellen die worden geactiveerd wanneer een geheugenlocatie wordt geopend. Gebruik de opdracht ba (onderbreking bij toegang) met de volgende syntaxis.

ba <access> <size> <address> {options}
Optie Beschrijving

e

uitvoeren (wanneer cpu een instructie ophaalt van het adres)

r

lezen/schrijven (wanneer de CPU naar het adres leest of schrijft)

w

schrijven (wanneer de CPU naar het adres toe schrijft)

Houd er rekening mee dat u op elk gewenst moment slechts vier onderbrekingspunten voor gegevens kunt instellen en het is aan u om ervoor te zorgen dat u uw gegevens correct uitlijnt of dat u het onderbrekingspunt niet activeert (woorden moeten eindigen op adressen die deelbaar zijn door 2, dwords moeten deelbaar zijn door 4 en quadwords met 0 of 8)

Als u bijvoorbeeld een onderbrekingspunt voor lezen/schrijven wilt instellen op een specifiek geheugenadres, gebruikt u een opdracht zoals deze.

ba r 4 fffff800`7bc9eff0

Status van onderbrekingspunt wijzigen

U kunt bestaande onderbrekingspunten wijzigen met behulp van de volgende opdrachten.

Bl

Onderbrekingspunten opsommen.

v. Chr.

Hiermee wordt een onderbrekingspunt uit de lijst gewist. Gebruik 'bc *' om alle onderbreekpunten te wissen.

Bd

Hiermee schakelt u een onderbrekingspunt uit. Gebruik bd * om alle onderbrekingspunten uit te schakelen.

zijn

Hiermee schakelt u een onderbrekingspunt in. Gebruik be * om alle onderbrekingspunten in te schakelen.

U kunt ook onderbrekingspunten wijzigen door bewerken>onderbrekingspunten te selecteren. Het dialoogvenster Onderbrekingspunt werkt alleen met bestaande onderbrekingspunten. Nieuwe onderbrekingspunten moeten worden ingesteld vanaf de opdrachtregel.

Een onderbrekingspunt instellen op MixerVolume

Verschillende onderdelen van de audiostuurprogrammacode worden aangeroepen om te reageren op verschillende gebeurtenissen, nadat het apparaatstuurprogramma is geladen. In de volgende sectie stellen we een onderbrekingspunt in dat wordt geactiveerd wanneer de gebruiker de volumeregeling voor het virtuele audiostuurprogramma aanpast.

Voer de volgende stappen uit om een onderbrekingspunt in mixervolume in te stellen.

  1. <- Op het hostsysteem

    Als u de methode wilt vinden waarmee het volume wordt gewijzigd, gebruikt u de x-opdracht om de symbolen in CAdapterCommon weer te geven die het tekenreeksvolume bevatten.

    kd> x tabletaudiosample!CAdapterCommon::*
    ...
    fffff800`7bce26a0 tabletaudiosample!CAdapterCommon::MixerVolumeWrite (unsigned long, unsigned long, long)
    …
    

    Gebruik Ctrl+F om omhoog te zoeken in de uitvoer voor volume en zoek de methode MixerVolumeWrite.

  2. Wis de vorige onderbrekingspunten met bc *.

  3. Stel een symboolonderbrekingspunt in op de CAdapterCommon::MixerVolumeWrite routine met behulp van de volgende opdracht.

    kd> bm tabletaudiosample!CAdapterCommon::MixerVolumeWrite
      1: fffff801`177b26a0 @!"tabletaudiosample!CAdapterCommon::MixerVolumeWrite"
    
  4. Vermeld de onderbrekingspunten om te bevestigen dat het onderbrekingspunt juist is ingesteld.

    kd> bl
    1 e fffff801`177b26a0 [c:\WDK_Samples\audio\sysvad\common.cpp @ 1668]    0001 (0001) tabletaudiosample!CAdapterCommon::MixerVolumeWrite
    
  5. Start de uitvoering van code opnieuw op het doelsysteem door de go-opdracht g te typen.

  6. Selecteer hardware en geluid> in het Configuratiescherm. Selecteer het sinkbeschrijvingsvoorbeeld (of klik erop met de rechtermuisknop) en selecteer Eigenschappen. Selecteer het tabblad Niveaus . Pas het schuifregelaarvolume aan.

  7. Dit moet ertoe leiden dat het onderbrekingspunt voor foutopsporing van SetMixerVolume wordt geactiveerd en dat de uitvoering van de stuurprogrammacode op het doelsysteem moet worden gestopt.

    kd> g
    Breakpoint 1 hit
    tabletaudiosample!CAdapterCommon::MixerVolumeWrite:
    fffff801`177b26a0 44894c2420      mov     dword ptr [rsp+20h],r9d
    

    Je zou op deze regel in common.cpp moeten stoppen.

    {
        if (m_pHW)
        {
            m_pHW->SetMixerVolume(Index, Channel, Value);
        }
    } // MixerVolumeWrite
    
  8. Gebruik de dv-opdracht om de huidige variabelen en de bijbehorende waarden weer te geven. Meer informatie over variabelen vindt u in de volgende sectie van dit lab.

    2: kd> dv
               this = 0x00000000`00000010
             ulNode = 0x344
          ulChannel = 0x210a45f8
            lVolume = 0n24
    
  9. Druk op F10 om de code te doorlopen.

  10. Druk op F5 om de uitvoering van de MixerVolumeWrite-code te voltooien.

Samenvatting: stap voor stap doorlopen van code vanuit het opdrachtvenster van de debugger

Hier volgen de opdrachten die u kunt gebruiken om uw code te doorlopen (met de bijbehorende korte knipsels van het toetsenbord tussen haakjes).

  • Inbreken (Ctrl+Break) - deze opdracht onderbreekt een systeem zolang het systeem wordt uitgevoerd en in communicatie is met WinDbg (de toetscombinatie in de Kernel Debugger is Ctrl+C).

  • Stap over (F10): Dit commando zorgt ervoor dat de uitvoering van code stapsgewijs verloopt, één statement of één instructie tegelijk. Als er een aanroep wordt aangetroffen, gaat de uitvoering verder zonder de aangeroepen routine in te voeren. (Als de programmeertaal C of C++ is en WinDbg zich in de bronmodus bevindt, kan de bronmodus worden ingeschakeld of uitgeschakeld met behulp van Foutopsporing>Bronmodus).

  • Stap in (F11): deze opdracht lijkt op stap-over, behalve dat de uitvoering van een aanroep wel in de aangeroepen routine terechtkomt.

  • Stap uit (Shift+F11): deze opdracht zorgt ervoor dat de uitvoering doorgaat naar en wordt verlaten van de huidige routine (huidige plaats in de aanroepstack). Dit is handig als u genoeg van de routine hebt gezien.

  • Naar cursor uitvoeren (F7 of Ctrl+F10) – Plaats de cursor in een bron- of demontagevenster waar u wilt dat de uitvoering stopt en druk vervolgens op F7; de code-uitvoering zal tot dat punt doorgaan. Houd er rekening mee dat als de stroom van het uitvoeren van code niet het punt bereikt dat wordt aangegeven door de cursor (bijvoorbeeld een IF-instructie niet wordt uitgevoerd), wordt WinDbg niet verbroken, omdat de uitvoering van de code het aangegeven punt niet heeft bereikt.

  • Uitvoeren (F5): voer uit totdat er een onderbrekingspunt is bereikt of er een gebeurtenis zoals een bugcontrole optreedt.

Geavanceerde opties

  • Instructies instellen voor de huidige regel (Ctrl+Shift+I): in een bronvenster kunt u de cursor op een regel plaatsen, deze sneltoets invoeren en de uitvoering van code begint vanaf dat moment zodra u het laat doorgaan (bijvoorbeeld met F5 of F10). Dit is handig als u een reeks opnieuw wilt proberen, maar dit vereist enige zorg. Registers en variabelen worden bijvoorbeeld niet ingesteld op wat ze zouden zijn als de uitvoering van code die regel op natuurlijke wijze had bereikt.

  • Directe instelling van het eip-register - U kunt een waarde in het eip-register plaatsen en zodra u op F5 (of F10, F11, enzovoort) drukt, begint de uitvoering vanaf dat adres. Dit is vergelijkbaar met het instellen van een instructie voor de door de cursor aangewezen huidige regel, behalve dat u het adres van een assembly-instructie specificeert.

Het kan eenvoudiger zijn om de gebruikersinterface te doorlopen in plaats van vanaf de opdrachtregel, zodat deze methode wordt aanbevolen. Indien nodig kunnen de volgende opdrachten worden gebruikt om een bronbestand op de commandoregel door te lopen:

  • .lines - Informatie over de regelnummers van de bron inschakelen.

  • bp main - Stel het eerste onderbrekingspunt in aan het begin van je module.

  • l+t - Stap wordt uitgevoerd via de bronregel.

  • Selecteer Debug>Bronmodus om de bronmodus in te voeren; de L+t opdracht is niet voldoende.

  • l+s: bronlijnen worden weergegeven bij prompt.

  • g - Voer het programma uit totdat 'main' is ingevoerd.

  • p - Voer één bronregel uit.

Zie broncode opsporen in WinDbg (klassiek) in de referentiedocumentatie voor foutopsporing voor meer informatie.

Onderbrekingspunten instellen in code

U kunt een onderbrekingspunt instellen in code door de DebugBreak() instructie toe te voegen en het project opnieuw te bouwen en het stuurprogramma opnieuw te installeren. Dit onderbrekingspunt wordt geactiveerd telkens wanneer het stuurprogramma is ingeschakeld, dus het zou een techniek zijn die in de vroege ontwikkelingsfasen moet worden gebruikt, niet in productiecode. Deze techniek is niet zo flexibel als het dynamisch instellen van onderbrekingspunten met behulp van de onderbrekingspuntenopdrachten.

Tip: Mogelijk wilt u een kopie van het Sysvad-stuurprogramma behouden zonder het onderbrekingspunt dat is toegevoegd voor verder labwerk.

  1. Stel een onderbreking in die moet optreden telkens wanneer de methode AddDevice wordt uitgevoerd door de DebugBreak() instructie toe te voegen aan de voorbeeldcode.

    ...
        // 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. Volg alle stappen die eerder zijn beschreven om het stuurprogramma opnieuw te bouwen in Microsoft Visual Studio en installeer het opnieuw op de doelcomputer. Verwijder het bestaande stuurprogramma voordat u het bijgewerkte stuurprogramma installeert.

  3. Wis eventuele eerdere breekpunten en zorg ervoor dat de debugger is gekoppeld aan de doelcomputer.

  4. Wanneer de code wordt uitgevoerd en de DebugBreak-uitspraak bereikt, zal de uitvoering stoppen en wordt er een bericht weergegeven.

    KERNELBASE!DebugBreak:
    77b3b770 defe     __debugbreak
    

Sectie 8: Variabelen weergeven

In sectie 8 gebruikt u debugger-opdrachten om variabelen weer te geven.

Het kan handig zijn om variabelen te onderzoeken terwijl de code wordt uitgevoerd om te bevestigen dat de code werkt zoals verwacht. In dit lab worden variabelen onderzocht terwijl het audiostuurprogramma geluid produceert.

  1. Gebruik het dv-commando om de landinstellingvariabelen te onderzoeken die zijn verbonden met tabletaudiosample!CMiniportWaveRT::New*.

    kd> dv tabletaudiosample!CMiniportWaveRT::New*
    
  2. De vorige onderbrekingspunten wissen

    bc *
    
  3. Stel een symboolonderbrekingspunt in op de CMiniportWaveCyclicStreamMSVAD-routines met behulp van de volgende opdracht.

    0: kd> bm tabletaudiosample!CMiniportWaveRT::NewStream
      1: fffff801`177dffc0 @!"tabletaudiosample!CMiniportWaveRT::NewStream"
    
  4. Start de uitvoering van code opnieuw op het doelsysteem door de go-opdracht g te typen.

  5. -> Op het doelsysteem

    Zoek een klein mediabestand (zoals windows notification sound file met een .wav bestandsextensie) en selecteer het bestand om het af te spelen. U kunt bijvoorbeeld Ring05.wav in de map Windows\Media gebruiken.

  6. <- Op het hostsysteem

    Wanneer het mediabestand wordt afgespeeld, moet het onderbrekingspunt worden geactiveerd en moet de uitvoering van de stuurprogrammacode op het doelsysteem worden gestopt.

    Breakpoint 1 hit
    tabletaudiosample!CMiniportWaveRT::NewStream:
    fffff801`177dffc0 44894c2420      mov     dword ptr [rsp+20h],r9d
    

    In het broncodevenster moet de accolade bij de ingang van de functie NewStream worden gemarkeerd.

    /*++
    
    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. lokale variabelen

    U kunt de namen en waarden van alle lokale variabelen voor een bepaald frame weergeven door de opdracht dv te typen.

    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. DML gebruiken om variabelen weer te geven

    Als u DML wilt gebruiken om variabelen te verkennen, selecteert u de onderstreepte elementen. Met de selectieactie wordt een dx-opdracht (NatVis-expressie weergeven) gebouwd waarmee u kunt inzoomen op geneste gegevensstructuren.

    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. globale variabelen

    U kunt de geheugenlocatie van een globale variabele vinden door te typen? <variabelenaam>.

    0: kd> ? signalProcessingMode
    Evaluate expression: -52768896396472 = ffffd001`c8acd348
    
  10. Hiermee wordt de geheugenlocatie van de variabele geretourneerd, in dit geval ffffd001'c8acd348. U kunt de inhoud van de geheugenlocatie bekijken door de waarde van die locatie te dumpen door de dd-opdracht te typen met behulp van de geheugenlocatie die door de vorige opdracht is geretourneerd.

    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. U kunt ook variabelenamen gebruiken met de opdracht dd .

    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. Variabelen weergeven

    Gebruik het menu-item Weergeven>Lokale variabelen om lokale variabelen weer te geven. Deze interface biedt ook deze mogelijkheid om in te zoomen op complexere gegevensstructuren.

    WinDbg-interface met voorbeeldcode lokale variabelen en opdrachtvensters.

  13. Gebruik p of F10 om ongeveer 10 regels vooruit te stappen in de code totdat u de coderegel ntStatus = IsFormatSupported(Pin, Capture, DataFormat) markeert.

        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. Gebruik de dv-opdracht om de namen en waarden van alle lokale variabelen voor een bepaald frame weer te geven. Zoals verwacht verschillen de waarden van de laatste keer dat we deze opdracht hebben uitgevoerd, omdat er extra code is uitgevoerd die de lokale variabelen wijzigt en sommige variabelen zich nu niet in het huidige frame bevinden of de bijbehorende waarden zijn gewijzigd.

    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
    

Sectie 9: Oproepstacks weergeven

In sectie 9 bekijkt u aanroepstacks om de aanroeper-/aanroepcode te onderzoeken.

De call stack is de keten van functie-aanroepen die hebben geleid tot de huidige locatie van de programmateller. De bovenste functie op de aanroepstack is de huidige functie, en de volgende functie is de functie die de huidige functie heeft aangeroepen, enzovoort.

Als u de aanroepstack wilt weergeven, gebruikt u de k*-opdrachten:

Kb

Geeft de stack en de eerste drie parameters weer.

Kp

Geeft de stacks en de volledige lijst met parameters weer.

kN

Hiermee kunt u de stapel zien met de framegegevens ernaast.

Als u de oproepstack beschikbaar wilt houden, kunt u De>oproepstack weergeven selecteren om deze weer te geven. Selecteer de kolommen boven aan het venster om de weergave van aanvullende informatie in te schakelen.

WinDbg-interface met het aanroepstackvenster.

Deze uitvoer toont de aanroepstack tijdens het opsporen van fouten in de voorbeeldadaptercode in een onderbrekingsstatus.

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

U kunt DML gebruiken om de code verder te verkennen. Wanneer u de eerste 00 invoer selecteert, wordt de opdracht .frame (Lokale context instellen) gebruikt om de context in te stellen. Vervolgens geeft de dv-opdracht (Lokale variabelen weergeven) de lokale variabelen weer.

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

Sectie 10: Processen en threads weergeven

In sectie 10 gebruikt u foutopsporingsprogrammaopdrachten om processen en threads weer te geven.

Verwerken

Als u de huidige procescontext wilt wijzigen, gebruikt u de opdracht .process process<>. In het volgende voorbeeld ziet u hoe u een proces identificeert en naar de context kunt overschakelen.

  • Gebruik de !process opdracht om het huidige proces weer te geven dat betrokken is bij het afspelen van het geluid.

    Zie !process voor meer informatie

De uitvoer laat zien dat het proces is gekoppeld aan audiodg.exe. Als u zich nog steeds op het onderbrekingspunt bevindt dat in de vorige sectie van dit onderwerp wordt beschreven, moet het huidige proces worden gekoppeld aan de audiodg.exe afbeelding.

<- Op het hostsysteem

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

Houd er rekening mee dat een van de threads die aan dit proces zijn gekoppeld, de status ACTIEF heeft. Deze thread ondersteunde het afspelen van de mediaclip toen het onderbrekingspunt werd bereikt.

Gebruik de opdracht !process 0 0 om samenvattingsinformatie weer te geven voor alle processen. In de uitvoer van de opdracht gebruikt u Ctrl+F om de proces-id te zoeken voor het proces dat is gekoppeld aan de audiodg.exe afbeelding. In het onderstaande voorbeeld is de proces-id ffffe001d147c840.

Noteer de proces-id die is gekoppeld aan audiodg.exe op uw pc voor later gebruik in dit lab. ________________________

...

PROCESS ffffe001d147c840
    SessionId: 0  Cid: 10f0    Peb: ee6cf8a000  ParentCid: 0434
    DirBase: d2122000  ObjectTable: ffffc0001f191ac0  HandleCount: <Data Not Accessible>
    Image: audiodg.exe
...

Voer g in het foutopsporingsprogramma in om de code door te sturen totdat de mediaclip is afgespeeld. Meld u vervolgens aan bij het foutopsporingsprogramma door op Ctrl+ScrLk (Ctrl+Break) te drukken. Gebruik de opdracht !process om te bevestigen dat u nu een ander proces uitvoert.

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

In de bovenstaande uitvoer ziet u dat een ander systeemproces van ffffe001cd0ad040 wordt uitgevoerd. De afbeeldingsnaam toont Systeem, niet audiodg.exe.

Gebruik nu de opdracht !process om over te schakelen naar het proces dat is gekoppeld aan audiodg.exe. In het voorbeeld is de proces-id ffffe001d147c840. Vervang de proces-id in het voorbeeld door uw proces-id, die u eerder hebt vastgelegd.

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.

Omdat deze code niet actief is, hebben alle threads de status WAIT, zoals verwacht.

Discussies

De opdrachten voor het weergeven en instellen van threads zijn vergelijkbaar met die van processen. Gebruik de opdracht !thread om threads weer te geven. Gebruik .thread om de huidige threads in te stellen.

Als u threads wilt verkennen die zijn gekoppeld aan de mediaspeler, speelt u de mediaclip opnieuw af. Als het onderbrekingspunt dat in de vorige sectie wordt beschreven, nog steeds aanwezig is, zult u stoppen binnen de context van audiodg.exe.

Gebruik de !thread -1 0 om korte informatie weer te geven voor de huidige thread. Hier ziet u het threadadres, de thread- en proces-id's, het TEB-adres (Thread Environment Block), het adres van de Win32-functie (indien aanwezig) dat de thread is gemaakt voor uitvoering en de planningsstatus van de thread.

0: kd> !thread -1 0
THREAD ffffe001d3a27040  Cid 10f0.17f4  Teb: 000000ee6cf9d000 Win32Thread: 0000000000000000 RUNNING on processor 0

Als u meer informatie wilt weergeven over de thread die wordt uitgevoerd, typt u !thread. Informatie die vergelijkbaar is met het volgende, moet worden weergegeven.

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

Gebruik de opdracht k om de aanroepstack weer te geven die aan de thread is gekoppeld.

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

Voer g in het foutopsporingsprogramma in om de code door te sturen totdat de mediaclip is afgespeeld. Meld u vervolgens aan bij het foutopsporingsprogramma door op Ctrl - ScrLk (Ctrl-Break) te drukken. Gebruik de opdracht !thread om te bevestigen dat u nu een andere thread uitvoert.

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

De naam van de afbeelding is rundll32.exe, wat inderdaad niet de naam van de afbeelding is die hoort bij het afspelen van de mediaclip.

Notitie Als u de huidige thread wilt instellen, typt u het threadnummer< van de thread>.

Zie de volgende verwijzingen voor meer informatie over threads en processen:

Threads en processen

Contexten wijzigen

Sectie 11: IRQL, registers en disassemblage

De opgeslagen IRQL weergeven

In sectie 11 geeft u de IRQL en de inhoud van de regsisters weer.

<- Op het hostsysteem

Het onderbrekingsaanvraagniveau (IRQL) wordt gebruikt om de prioriteit van interrupt-onderhoud te beheren. Elke processor heeft een IRQL-niveau dat threads kunnen verhogen of verlagen. Onderbrekingen die optreden bij of onder de IRQL-instelling van de processor, worden gemaskeerd en verstoren de huidige bewerking niet. Onderbrekingen die zich boven de IRQL-instelling van de processor voordoen, hebben voorrang op de huidige bewerking. De extensie !irql geeft het onderbrekingsaanvraagniveau (IRQL) weer op de huidige processor van de doelcomputer voordat het foutopsporingsprogramma is opgetreden. Als de doelcomputer inbreekt in het foutopsporingsprogramma, verandert de IRQL, maar de IRQL die net voor de onderbreking door het foutopsporingsprogramma effectief was, wordt opgeslagen en weergegeven door !irql.

0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)

< De registers en demontage bekijken

De registers weergeven

Geef de inhoud van de registers voor de huidige thread op de huidige processor weer met behulp van de opdracht r (Registers).

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

U kunt ook de inhoud van de registers weergeven door Weergave>Registerste selecteren.

Schermopname van het venster WinDbg-registers met ongeveer 12 registers.

Het weergeven van de inhoud van de registers kan handig zijn bij het doorlopen van de uitvoering van de assemblytaalcode en in andere scenario's. Zie r (registers) voor meer informatie.

Zie x86-architectuur en x64-architectuur voor informatie over de inhoud van het register.

Demontage

U kunt de code die wordt uitgevoerd, demonteren om de code voor de assemblytaal weer te geven die wordt uitgevoerd door Weergave>demontage te selecteren.

Schermopname van WinDbg-disassemblievenster met assemblytaalcode.

Zie Annotated x86 Disassembly en Annotated x64 Disassembly voor meer informatie over de disassemblage van assemblytaal.

Sectie 12: Werken met geheugen

In sectie 12 gebruikt u foutopsporingsprogrammaopdrachten om de inhoud van het geheugen weer te geven.

Geheugen weergeven

Mogelijk moet u het geheugen onderzoeken om een probleem te identificeren of variabelen, aanwijzers enzovoort te inspecteren. U kunt geheugen weergeven door een van de volgende d* <-adresopdrachten> te typen.

Db

Geeft gegevens weer in bytewaarden en ASCII-tekens.

Dd

Geeft gegevens weer als dubbele brede woorden (4 bytes).

Du

Geeft gegevens weer als Unicode-tekens.

Dw

Geeft gegevens weer als woordwaarden (2 bytes) en ASCII-tekens.

Notitie Als u een ongeldig adres probeert weer te geven, wordt de inhoud ervan weergegeven als vraagtekens (?).

U kunt ook het geheugen bekijken door Geheugen weergeven> te selecteren. Gebruik de keuzelijst Weergave-indeling om te wijzigen hoe het geheugen wordt weergegeven.

Schermopname van het weergavevenster van WinDbg met verschillende opties voor weergaveformaten.

  1. Als u gegevens wilt weergeven die zijn gekoppeld aan de volumeregeling, stelt u een onderbrekingspunt in op de routine PropertyHandlerAudioEngineVolumeLevel met behulp van de bm-opdracht. Voordat we het nieuwe onderbrekingspunt instellen, wissen we alle vorige onderbrekingspunten met bc *.

    kd> bc *
    
  2. Stel een onderbrekingspunt in op de routine PropertyHandlerAudioEngineVolumeLevel met behulp van de bm-opdracht.

    kd> bm tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  3. Vermeld de onderbrekingspunten om te bevestigen dat het onderbrekingspunt juist is ingesteld.

    kd> bl
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  4. Gebruik de opdracht g om de uitvoering van code opnieuw te starten.

    Pas op het doelsysteem het volume in het systeemvak aan. Hierdoor wordt het onderbrekingspunt geactiveerd.

    Breakpoint 1 hit
    tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume:
    fffff80f`02c3a4b0 44894c2420      mov     dword ptr [rsp+20h],r9d
    
  5. Gebruik de> menuopdrachtLokaal weergeven om lokale variabelen weer te geven. Noteer de huidige waarde van de variabele IVolume.

  6. U kunt het gegevenstype en de huidige waarde voor de variabele IVolume in de voorbeeldcode weergeven door de opdracht dt en de naam van de variabele te typen.

    kd> dt lVolume
    Local var @ 0xa011ea50 Type long
    0n-6291456
    
  7. Het onderbrekingspunt wordt bereikt bij het invoeren van 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. Probeer de waarde weer te geven op de geheugenlocatie van IVolume met behulp van de opdracht dt (Weergavetype).

    kd> dt dt lVolume
    Local var @ 0xffffb780b7eee664 Type long
    0n0
    

    Omdat de variabele nog moet worden gedefinieerd, bevat deze geen informatie.

  9. Druk op F10 om door te gaan naar de laatste regel code in SetDeviceChannelVolume.

        return ntStatus;
    
  10. Geef de waarde weer op de geheugenlocatie van IVolume met behulp van de opdracht dt (Weergavetype).

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

    Nu de variabele actief is, wordt in dit voorbeeld een waarde van 6291456 weergegeven.

  11. U kunt ook de geheugenlocatie van IVolume weergeven met behulp van de ? (Expressie evalueren) bevelen.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  12. Het adres dat wordt weergegeven, ffffb780'b7eee664 is het adres van de variabele lVolume. Gebruik de opdracht dd om de inhoud van het geheugen op die locatie weer te geven.

    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. U kunt de eerste vier bytes van een adres weergeven door de bereikparameter L4 op te geven.

    kd> dd ffffb780`b7eee664 l4
    ffffb780`b7eee664  ffa00000 00000018 00000000 c52d7008
    
  14. Als u de verschillende typen geheugenuitvoer wilt zien, typt u de opdrachten du, da en 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  ....(...........
    

    Gebruik de optie df float om gegevens weer te geven als drijvendekommagetallen met één precisie (4 bytes).

    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
    

Schrijven naar geheugen

Net als de opdrachten die worden gebruikt voor het lezen van geheugen, kunt u de e*-opdrachten gebruiken om de inhoud van het geheugen te wijzigen.

Opdracht Beschrijving

Stuk

ASCII-tekenreeks (niet null-beëindigd)

EU

Unicode-tekenreeks (niet null-beëindigd)

Ew

Word-waarden (2 bytes)

eza

ASCII-tekenreeks die door NULL is beëindigd

ezu

Unicode-tekenreeks die is beëindigd met NULL

Eb

Bytewaarden

ed

Dubbele woordwaarden (4 bytes)

In het volgende voorbeeld ziet u hoe u geheugen overschrijft.

  1. Zoek eerst het adres van het lVolume dat wordt gebruikt in de voorbeeldcode.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  2. Overschrijf dat geheugenadres met nieuwe tekens met behulp van de eb-opdracht.

    kd> eb 0xffffb780`b7eee664 11 11 11 11 11
    
  3. Geef de geheugenlocatie weer om te bevestigen dat de tekens zijn overschreven door de db-opdracht te typen.

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

U kunt ook de inhoud van het geheugen wijzigen in een watch-venster of locals-venster. Voor het kijkvenster kunt u variabelen zien die buiten de context van het huidige frame zijn. Het wijzigen ervan is niet relevant als ze niet in context zijn.

Sectie 13: De WinDbg-sessie beëindigen

<-Op het hostsysteem

Als u de debugger gekoppeld wilt laten, maar aan de doelcomputer wilt werken, wist eventuele onderbrekingspunten met behulp van bc *, zodat de doelcomputer geen verbinding zal proberen te maken met het foutopsporingsprogramma van de hostcomputer. Gebruik vervolgens de opdracht g om de doelcomputer weer te laten draaien.

Als u de foutopsporingssessie wilt beëindigen, schakelt u op het hostsysteem in het foutopsporingsprogramma in en voert u de opdracht qd (Afsluiten en loskoppelen) in of selecteert u Stop Debugging in het menu.

0: kd> qd

Zie Voor meer informatie het beëindigen van een foutopsporingssessie in WinDbg (klassiek) in de referentiedocumentatie voor foutopsporing.

Sectie 14: Windows debugbronnen

Aanvullende informatie is beschikbaar in Windows-foutopsporing. Sommige van deze boeken gebruiken oudere versies van Windows, zoals Windows Vista, in hun voorbeelden, maar de concepten die worden besproken, zijn van toepassing op de meeste versies van Windows.

Boeken

  • Geavanceerde Windows-foutopsporing door Mario Hewardt en Daniel Pravat

  • Binnen Windows-foutopsporing: een praktische handleiding voor het opsporen en traceren van strategieën in Windows® door Tarik Soulami

  • Windows Internals van Pavel Yosifovich, Alex Ionescu, Mark Russinovich en David Salomon

Video

De Defrag Tools Show WinDbg Afleveringen 13-29: </shows/defrag-tools/>

Trainingsleveranciers:

OSR - https://www.osr.com/

Zie ook

Aan de slag met Windows-foutopsporing