Sdílet prostřednictvím


Ladění ovladačů – podrobné testovací prostředí (režim jádra Sysvad)

Tato laboratoř poskytuje praktická cvičení, která ukazují, jak odstraňovat problémy s ovladačem zvukového zařízení Sysvad v režimu jádra.

Ladicí program systému Microsoft Windows (WinDbg) je výkonný nástroj pro ladění založený na systému Windows, který můžete použít k provádění ladění v uživatelském režimu a režimu jádra. WinDbg poskytuje ladění na úrovni zdroje pro jádro Windows, ovladače režimu jádra a systémové služby a také aplikace a ovladače v uživatelském režimu.

WinDbg může procházet zdrojový kód, nastavit zarážky, zobrazit proměnné (včetně objektů C++), trasování zásobníku a paměti. Jeho příkazové okno ladicího programu umožňuje uživateli vydat širokou škálu příkazů.

Nastavení testovacího prostředí

K dokončení testovacího prostředí budete potřebovat následující hardware:

  • Přenosný počítač nebo stolní počítač (hostitel) s Windows 10
  • Přenosný počítač nebo stolní počítač (cíl) s Windows 10
  • Rozbočovač/směrovač sítě a síťové kabely pro připojení dvou počítačů
  • Přístup k internetu pro stahování souborů symbolů

Pro dokončení laboratoře budete potřebovat následující software.

  • Microsoft Visual Studio 2017
  • Windows Software Development Kit (SDK) pro Windows 10
  • Windows Driver Kit (WDK) pro Windows 10
  • Ukázkový zvukový ovladač Sysvad pro Windows 10

Informace o stažení a instalaci WDK naleznete v tématu Stažení sady Windows Driver Kit (WDK).

Průvodce laděním sysvadu

Toto cvičení vás provede procesem ladění ovladače režimu jádra. Cvičení používají ukázku virtuálního zvukového ovladače Syvad. Vzhledem k tomu, že ovladač zvuku Syvad nepracuje se skutečným zvukovým hardwarem, lze ho použít na většině zařízení. Laboratoř se zabývá následujícími úlohami:

Echo Driver Lab

Ovladač Echo je jednodušší ovladač než ovladač zvuku Sysvad. Pokud s WinDbg teprve začínáte, možná budete chtít nejprve dokončit ladění univerzálních ovladačů – podrobné cvičení (režim jádra Echo). Toto cvičení znovu použije pokyny k nastavení z tohoto testovacího prostředí, takže pokud jste dokončili toto cvičení, můžete zde přeskočit části 1 a 2.

Oddíl 1: Připojení k relaci WinDbg v režimu jádra

V části 1 nakonfigurujete ladění sítě v hostitelském a cílovém systému.

Počítače v tomto cvičení musí být nakonfigurované tak, aby pro ladění jádra používaly připojení k síti Ethernet.

Tato laboratoř používá dva počítače. WinDbg běží v hostitelském systému a ovladač Sysvad běží v cílovém systému.

Pomocí síťového rozbočovače/směrovače a síťových kabelů připojte dva počítače.

Diagram znázorňující dva počítače připojené přes síťový rozbočovač nebo směrovač

Pokud chcete pracovat s aplikacemi v režimu jádra a používat WinDbg, doporučujeme použít síť KDNET přes ethernetový přenos. Informace o použití přenosového protokolu Ethernet naleznete v tématu Začínáme s WinDbg (Kernel-Mode). Další informace o nastavení cílového počítače naleznete v tématu Příprava počítače pro ruční nasazení ovladačů a nastavení ladění jádra sítě KDNET automaticky.

Konfigurace ladění v režimu jádra pomocí ethernetu

Pokud chcete v cílovém systému povolit ladění v režimu jádra, proveďte následující kroky.

<– na hostitelském systému

  1. Otevřete příkazový řádek v hostitelském systému a zadejte ipconfig /all a určete jeho IP adresu.
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. Záznam IP adresy hostitelského systému: ______________________________________

  2. Záznam názvu hostitele hostitelského systému: ______________________________________

-> V cílovém systému

  1. Otevřete příkazový řádek v cílovém systému a pomocí příkazu ping potvrďte síťové připojení mezi těmito dvěma systémy. Použijte skutečnou IP adresu hostitelského systému, který jste si poznamenali místo 169.182.1.1, která se zobrazí v ukázkovém výstupu.
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

Pokud chcete v cílovém systému povolit ladění v režimu jádra pomocí nástroje KDNET, proveďte následující kroky.

  1. V hostitelském systému vyhledejte adresář WDK KDNET. Ve výchozím nastavení se nachází tady.

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

V tomto cvičení se předpokládá, že na obou počítačích – jak na cílovém, tak na hostitelském – běží 64bitová verze Windows. Pokud tomu tak není, nejlepší je spustit stejnou bitovou verzi nástrojů na hostiteli, na kterém je cíl spuštěný. Pokud například cíl používá 32bitovou verzi Windows, spusťte na hostiteli 32 verzi ladicího programu. Další informace naleznete v tématu Volba 32bitové nebo 64bitové nástroje ladění.

  1. Vyhledejte tyto dva soubory a zkopírujte je do sdílené síťové složky nebo na USB flash disk, aby byly k dispozici na cílovém počítači.

    kdnet.exe

    VerifiedNICList.xml

  2. Na cílovém počítači otevřete okno příkazového řádku jako správce. Zadáním tohoto příkazu ověřte, že je síťová karta na cílovém počítači podporovaná.

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. Zadáním tohoto příkazu nastavte IP adresu hostitelského systému. Použijte skutečnou IP adresu hostitelského systému, který jste si poznamenali místo 169.182.1.1, která se zobrazí v ukázkovém výstupu. Vyberte jedinečnou adresu portu pro každou dvojici cíle nebo hostitele, se kterou pracujete, například 50010.
C:\>kdnet 169.182.1.1 50010

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

Důležité

Před použitím BCDEdit ke změně informací o spuštění může být nutné dočasně pozastavit funkce zabezpečení systému Windows, jako je BitLocker a Zabezpečené spouštění na testovacím počítači. Po dokončení testování opět aktivujte tyto funkce zabezpečení a odpovídajícím způsobem zacházejte s testovacím počítačem, když jsou bezpečnostní funkce vypnuté. Zabezpečené spouštění je obvykle zakázané v rozhraní UEFI. Pokud chcete získat přístup k nastavení UEFI, použijte System, Recovery, Advanced start-up. Při restartování vyberte Řešení potíží, Upřesnit možnosti, Nastavení firmwaru UEFI. Při nesprávném nastavení možností rozhraní UEFI a zakázání BitLockeru může dojít k nefunkčnosti systému, proto postupujte opatrně.

  1. Zadáním tohoto příkazu potvrďte, že jsou správně nastavené dbgsettings.
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.

Zkopírujte automaticky vygenerovaný jedinečný klíč do textového souboru, abyste ho nemuseli zadávat do hostitelského počítače. Zkopírujte textový soubor s klíčem do hostitelského systému.

PoznámkaBrány firewall a ladicí programy

Pokud se zobrazí automaticky otevíraná zpráva z firewallu a chcete použít ladicí program, zaškrtněte všechna tři políčka.

Snímek obrazovky s výstrahou zabezpečení systému Windows označující, že brána Windows Firewall zablokovala některé funkce aplikace

<– na hostitelském systému

  1. Na hostitelském počítači otevřete okno příkazového řádku jako správce. Přejděte do adresáře WinDbg.exe. Použijeme x64version WinDbg.exe ze sady Windows Driver Kit (WDK), která byla nainstalována jako součást instalace sady Windows Kit.
C:\> Cd C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 
  1. Spusťte WinDbg s laděním vzdáleného uživatele pomocí následujícího příkazu. Hodnota klíče a portu odpovídají tomu, co jste nastavili dříve pomocí BCDEdit v cíli.
C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p

->V cílovém systému

Restartujte cílový systém.

<-V hostitelském systému

Za minutu nebo dvě by se měl v hostitelském systému zobrazit výstup ladění.

Snímek obrazovky ladicího programu systému Windows zobrazující výstup příkazového okna z živého připojení jádra

Příkazové okno ladicího programu je primární okno s informacemi o ladění ve WinDbg. V tomto okně můžete zadat příkazy ladicího programu a zobrazit výstup příkazu.

Příkazové okno ladicího programu je rozdělené na dva panely. Příkazy zadáte do menšího podokna (podokno pro zadávání příkazů) v dolní části okna a zobrazíte výstup příkazu ve větším podokně v horní části okna.

V podokně zadávání příkazů můžete procházet historii příkazů pomocí šipky nahoru a šipky dolů. Když se zobrazí nějaký příkaz, můžete ho upravit nebo ho spustit stisknutím klávesy ENTER .

Oddíl 2: Příkazy a techniky ladění v režimu jádra

V oddílu 2 použijete ladicí příkazy k zobrazení informací o cílovém systému.

<– na hostitelském systému

Povolte Debugger Markup Language (DML) pomocí .prefer_dml

Některé ladicí příkazy zobrazují text pomocí jazyka značek ladicího programu, který můžete vybrat, abyste mohli rychle shromáždit další informace.

  1. Pomocí kombinace kláves Ctrl+Break (Scroll Lock) ve WinDBg rozdělte kód spuštěný v cílovém systému. Reakce cílového systému může chvíli trvat.
  2. Do příkazového okna ladicího programu zadejte následující příkaz, který povolí DML.
0: kd> .prefer_dml 1
DML versions of commands on by default

Získání nápovědy pomocí .hh

Pomocí příkazu .hh můžete získat přístup k nápovědě k referenčnímu příkazu.

  1. Zadejte následující příkaz ke zobrazení referenční nápovědy k příkazu pro .prefer_dml.
    0: kd> .hh .prefer_dml
    

Soubor nápovědy pro Debugger zobrazí nápovědu pro příkaz .prefer_dml.

Snímek obrazovky aplikace Nápověda pro ladicí program zobrazující nápovědu pro příkaz .prefer-dml

Zobrazení verze Windows v cílovém systému

  1. Podrobné informace o verzi cílového systému zobrazíte zadáním příkazu vertarget (Zobrazit verzi cílového počítače) v okně WinDbg.
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

Výpis načtených modulů

  1. V okně WinDbg můžete ověřit, že pracujete se správným procesem režimu jádra, zadáním příkazu lm (List Loaded Modules) pro zobrazení nahraných modulů.
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
...

Poznámka Výstup, který byl vynechán, je označen "... v této laboratoři.

Protože jsme dosud nenastavili cestu k symbolům a nenačetli symboly, jsou v ladicím programu k dispozici pouze omezené informace.

Oddíl 3: Stažení a sestavení zvukového ovladače Sysvad

V části 3 si stáhnete a sestavíte ovladač zvuku Sysvad.

Obvykle byste při použití WinDbg pracovali s vlastním kódem ovladače. Pokud se chcete seznámit s laděním zvukových ovladačů, je použit virtuální zvukový ukázkový ovladač Sysvad. cs-CZ: Tato ukázka se používá k ilustraci toho, jak můžete projít každý krok nativního kódu v režimu jádra. Tato technika může být velmi cenná pro ladění složitých problémů s kódem v režimu jádra.

Pokud chcete stáhnout a sestavit ukázkový zvukový ovladač Sysvad, proveďte následující kroky.

  1. Stažení a extrahování ukázky zvuku Sysvad z GitHubu

    Ukázku sysvadu a Readme.md soubor můžete zobrazit v prohlížeči tady:

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

    Snímek obrazovky úložiště GitHub zobrazující obecnou složku a tlačítko Stáhnout ZIP

    V tomto cvičení se dozvíte, jak stáhnout ukázky univerzálních ovladačů v jednom souboru ZIP.

    a. Stáhněte si soubor master.zip na místní pevný disk.

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

    b) Vyberte a podržte (nebo klikněte pravým tlačítkem) Windows-driver-samples-master.zipa zvolte Extrahovat vše. Zadejte novou složku nebo přejděte k existující složce, do které se budou ukládat extrahované soubory. Můžete například zadat C:\WDK_Samples\ jako novou složku, do které se soubory extrahují.

    c) Po extrahování souborů přejděte do následující podsložky.

    C:\WDK_Samples\Sysvad

  2. Otevřete řešení ovladače ve Visual Studiu

    V sadě Visual Studio vyberte Soubor>otevřít>projekt nebo řešení... a přejděte do složky, která obsahuje extrahované soubory (například C:\WDK_Samples\Sysvad). Poklikejte na soubor řešení Syvad .

    V sadě Visual Studio vyhledejte Průzkumníka řešení. (Pokud tato možnost ještě není otevřená, v nabídce Zobrazení zvolte Průzkumníka řešení.) V Průzkumníku řešení uvidíte jedno řešení, které má řadu projektů.

    Snímek obrazovky sady Visual Studio se souborem adapter.cpp načteným z projektu Sysvad

  3. Nastavení konfigurace a platformy ukázky

    V průzkumníku řešení vyberte a podržte (nebo klikněte pravým tlačítkem) na řešení 'sysvad' (7 z 7 projektů) a zvolte Configuration Manager. Ujistěte se, že nastavení konfigurace a platformy jsou pro čtyři projekty stejné. Ve výchozím nastavení je konfigurace nastavená na "Win10 Debug" (Ladění Win10) a pro všechny projekty je platforma nastavená na Win64. Pokud pro jeden projekt provedete nějaké změny konfigurace nebo platformy, musíte provést stejné změny pro zbývající tři projekty.

    Poznámka V tomto cvičení se předpokládá, že se používá 64bitová verze Windows. Pokud používáte 32bitovou verzi Windows, sestavte ovladač pro 32bitovou verzi.

  4. Kontrola podepisování ovladačů

    Vyhledejte TabletAudioSample. Otevřete stránku vlastností ovladače Sysvad a ujistěte se, že jerežim> ovladačů nastavený na testovací podpis.

  5. Je třeba upravit vzorky ovladačů tak, aby používaly hodnoty, které se nepřekrývají s existujícími ovladači. Přečtěte si Ze vzorového kódu do produkčního ovladače – co změnit v ukázkách o tom, jak vytvořit jedinečnou ukázku ovladače, která bude existovat společně se stávajícími skutečnými ovladači nainstalovanými ve Windows.

  6. Sestavení ukázky pomocí sady Visual Studio

    Ve Visual Studio vyberte Sestavení>Sestavit řešení.

    V oknech sestavení by se měla zobrazit zpráva, že sestavení pro všech šest projektů bylo úspěšné.

Návod

Pokud dojde k chybové zprávě sestavení, pomocí čísla chyby sestavení zjistěte opravu. Například chyba MSBuild MSB8040 popisuje, jak pracovat s knihovnami upravenými pro zmírnění Spectre.

  1. Najděte soubory vytvořených ovladačů

    V Průzkumníku souborů přejděte do složky, která obsahuje extrahované soubory ukázky. Například byste přešli na C:\WDK_Samples\Sysvad, pokud je to složka, kterou jste zadali dříve. Umístění zkompilovaných souborů ovladačů v této složce se liší v závislosti na konfiguraci a nastavení platformy, které jste vybrali v configuration Manageru. Pokud jste například nechali výchozí nastavení beze změny, uloží se kompilované soubory ovladačů do složky \x64\Debug pro 64bitové sestavení pro ladění.

    Přejděte do složky, která obsahuje vytvořené soubory pro ovladač TabletAudioSample:

    C:\WDK_Samples\Sysvad\TabletAudioSample\x64\Debug. Složka bude obsahovat tabletAudioSample .SYS ovladač, symbol pdp soubor a inf soubor. Budete také muset vyhledat knihovny DLL a soubory symbolů pro DelayAPO, KWSApo a KeywordDetectorContosoAdapter.

    K instalaci ovladače budete potřebovat následující soubory.

    Název souboru Popis
    TabletAudioSample.sys Soubor ovladače.
    TabletAudioSample.pdb Soubor symbolu ovladače.
    tabletaudiosample.inf Informační soubor (INF), který obsahuje informace potřebné k instalaci ovladače.
    KeywordDetectorContosoAdapter.dll Detektor ukázkových klíčových slov.
    KeywordDetectorContosoAdapter.pdb Soubor symbolu detektoru ukázkových klíčových slov.
    DelayAPO.dll Ukázkový zpožďovací APO.
    DelayAPO.pdb Soubor symbolů pro zpoždění APO.
    KWSApo.dll Ukázkový detektor klíčového slova APO.
    KWSApo.pdb Soubor symbolů rozpoznávače klíčových slov.
    TabletAudioSample.cer Soubor certifikátu TabletAudioSample.
  2. Vyhledejte jednotku USB nebo nastavte sdílenou síťovou složku pro zkopírování vytvořených souborů ovladačů z hostitele do cílového systému.

V další části zkopírujete kód do cílového systému a nainstalujete a otestujete ovladač.

Oddíl 4: Instalace ukázky zvukového ovladače Sysvad do cílového systému

V oddílu 4 použijete devcon k instalaci zvukového ovladače Sysvad.

-> V cílovém systému

Počítač, do kterého ovladač instalujete, se nazývá cílovým počítačem nebo testovacím počítačem. Obvykle se jedná o samostatný počítač od počítače, na kterém vyvíjíte a sestavujete balíček ovladačů. Počítač, na kterém vyvíjíte a vytváříte ovladač, se nazývá hostitelský počítač.

Proces přesunutí balíčku ovladače do cílového počítače a instalace ovladače se nazývá nasazení ovladače.

Než nasadíte ovladač, musíte cílový počítač připravit zapnutím testovacího podepisování. Až budete připraveni spustit ukázku sestaveného ovladače na cílovém systému.

Chcete-li nainstalovat ovladač do cílového systému, proveďte následující kroky.

  1. Povolit podepsané testovací ovladače

    Povolení spouštění testovacích podepsaných ovladačů:

    1. Otevřete nastavení windows.

    2. V Aktualizace a zabezpečenívyberte Obnovení.

    3. V části Rozšířené spuštěnívyberte Restartovat nyní.

    4. Po restartování počítače vyberte Odstranit potíže.

    5. Pak vyberte Upřesnit možnosti, Nastavení spuštění a pak vyberte Restartovat.

    6. Stisknutím klávesy F7 vyberte Zakázat vynucení podpisu ovladače.

    7. Počítač začne s novými hodnotami.

  2. -> V cílovém systému

    Instalace ovladače

    Následující pokyny ukazují, jak nainstalovat a otestovat ukázkový ovladač.

    Soubor INF vyžadovaný pro instalaci tohoto ovladače je TabletAudioSample.inf. Na cílovém počítači otevřete okno příkazového řádku jako správce. Přejděte do složky balíčku ovladače, klikněte pravým tlačítkem myši na soubor TabletAudioSample.inf a pak vyberte Nainstalovat.

    Zobrazí se dialogové okno označující, že testovací ovladač je nepodepsaný. Chcete-li pokračovat, vyberte Nainstalovat tento ovladač.

    Snímek obrazovky s upozorněním zabezpečení systému Windows s oznámením, že Systém Windows nemůže ověřit vydavatele

    Návod

     Pokud máte s instalací nějaké problémy, další informace najdete v následujícím souboru. %windir%\inf\setupapi.dev.log

    Podrobnější pokyny najdete v tématu Konfigurace počítače pro nasazení, testování a ladění ovladačů.

    Soubor INF obsahuje ID hardwaru pro instalaci tabletaudiosample.sys. Pro ukázku Syvadu je ID hardwaru: root\sysvad_TabletAudioSample

  3. Prozkoumání ovladače ve Správci zařízení

    V cílovém počítači v okně příkazového řádku zadejte devmgmt a otevřete Správce zařízení. Ve Správci zařízení v nabídce Zobrazit vyberte Zařízení podle typu.

    Ve stromu zařízení vyhledejte virtuální zvukové zařízení (WDM) – Ukázka tabletu v uzlu Zvukové zařízení. To je obvykle pod uzlem Ovladače zvuku, videa a her . Ověřte, že je nainstalovaný a aktivní.

    Zvýrazněte ovladač skutečného hardwaru na počítači ve Správci zařízení. Potom vyberte ovladač a podržte (nebo na něj klikněte pravým tlačítkem myši) a vyberte Zakázat.

    Potvrďte ve Správci zařízení, že ovladač zvukového hardwaru, zobrazí šipku dolů, která označuje, že je zakázaná.

    Snímek obrazovky stromu Správce zařízení se zvýrazněnou ukázkou tabletu virtuálního zvukového zařízení

    Po úspěšné instalaci ukázkového ovladače jste připraveni ho otestovat.

Otestování zvukového ovladače Sysvad

  1. V cílovém počítači v okně příkazového řádku zadejte devmgmt a otevřete Správce zařízení. Ve Správci zařízení v nabídce Zobrazit vyberte Zařízení podle typu. Ve stromu zařízení vyhledejte virtuální zvukové zařízení (WDM) – ukázka tabletu.

  2. Otevřete Ovládací panely a přejděte na Hardware a zvuk>Spravovat zvuková zařízení. V dialogovém okně Zvuk vyberte ikonu reproduktoru označenou jako virtuální zvukové zařízení (WDM) – Ukázka tabletu a pak vyberte Nastavit výchozí, ale nevybírejte OK. Tím zůstane dialogové okno Zvuk otevřené.

  3. Na cílovém počítači vyhledejte soubor MP3 nebo jiný zvukový soubor a poklikáním ho přehrajte. Poté v dialogovém okně Zvuk ověřte, zda je aktivita v indikátoru úrovně hlasitosti, který je přidružen k ovladači Virtuální zvukové zařízení (WDM) - Tablet Sample.

Oddíl 5: Zobrazení informací o ovladači pomocí WinDbg

V části 5 nastavíte cestu symbolu a pomocí příkazů ladicího programu jádra zobrazíte informace o ukázkovém ovladači Sysvad.

Symboly umožňují systému WinDbg zobrazit další informace, jako jsou názvy proměnných, které mohou být při ladění neocenitelné. WinDbg používá formáty symbolů ladění sady Microsoft Visual Studio pro ladění na úrovni zdroje. Z modulu, který obsahuje soubory symbolů PDB, má přístup k libovolnému symbolu nebo proměnné.

Pokud chcete načíst ladicí program, proveďte následující kroky.

<-V hostitelském systému

  1. Pokud jste uzavřeli ladicí program, znovu ho otevřete pomocí následujícího příkazu v okně příkazového řádku s právy správce. Nahraďte klíč a port tím, co jste předtím nakonfigurovali.

    C:\> WinDbg –k net:port=50010,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  2. Pomocí kombinace kláves Ctrl+Break (Scroll Lock) rozdělte kód spuštěný v cílovém systému.

Nastavení cesty symbolu

  1. Pokud chcete nastavit cestu symbolů k serveru symbolů Microsoftu v prostředí WinDbg, použijte příkaz .symfix .

    0: kd> .symfix
    
  2. Pokud chcete přidat umístění místního symbolu pro použití místních symbolů, přidejte cestu pomocí .sympath+ a pak .reload /f.

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

    Poznámka Příkaz .reload s parametrem /f force odstraní všechny informace o symbolech pro zadaný modul a znovu načte symboly. V některých případech tento příkaz přenačte nebo uvolní samotný modul.

Poznámka Abyste mohli používat pokročilé funkce, které poskytuje WinDbg, musíte načíst správné symboly. Pokud nemáte správně nakonfigurované symboly, obdržíte zprávy, které indikují, že symboly nejsou při pokusu o použití funkcí, které jsou závislé na symbolech, k dispozici.

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

Poznámka:Servery symbolů

Existuje řada přístupů, které lze použít k práci se symboly. V mnoha situacích můžete počítač nakonfigurovat tak, aby měl přístup k symbolům ze serveru symbolů, který Microsoft poskytuje v případě potřeby. Tento názorný postup předpokládá, že se tento přístup použije. Pokud jsou symboly ve vašem prostředí v jiném umístění, upravte postup použití daného umístění. Další informace naleznete v tématu Cesta symbolů pro ladicí program pro Windows.

Poznámka: Vysvětlení požadavků na symboly zdrojového kódu

Chcete-li provést ladění zdrojového kódu, je nutné sestavit kontrolovanou (ladicí) verzi binárních souborů. Kompilátor vytvoří soubory symbolů (soubory PDB). Tyto soubory symbolů zobrazí ladicí program, jak binární instrukce odpovídají zdrojovým řádkům. Samotné zdrojové soubory musí být také přístupné pro ladicí program.

Soubory symbolů neobsahují text zdrojového kódu. Při ladění je nejlepší, když linker neoptimalizuje váš kód. Ladění zdroje a přístup k místním proměnným jsou obtížnější a někdy téměř nemožné, pokud byl kód optimalizován. Pokud máte problémy se zobrazením místních proměnných nebo zdrojových řádků, nastavte následující možnosti sestavení.

set COMPILE_DEBUG=1

set ENABLE_OPTIMIZER=0

  1. Do příkazové oblasti ladicího programu zadejte následující příkaz, který zobrazí informace o ovladači Sysvad.

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

    Další informace naleznete na lm.

  2. Výběrem odkazu Procházet všechny globální symboly ve výstupu ladění zobrazíte informace o symbolech položek, které začínají písmenem a.

  3. Vzhledem k tomu, že je povoleno DML, jsou některé prvky výstupu aktivní odkazy, které můžete vybrat. Výběrem datového odkazu ve výstupu ladění zobrazíte informace o symbolech položek, které začínají písmenem a.

    0: kd> x /D /f tabletaudiosample!a*
     A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
    
    fffff806`9adb1000 tabletaudiosample!AddDevice (struct _DRIVER_OBJECT *, struct _DEVICE_OBJECT *)
    

    Informace najdete v tématu x (Prozkoumat symboly)..

  4. Rozšíření !lmi zobrazí podrobné informace o modulu. Zadejte !lmi tabletaudiosample. Výstup by se měl podobat textu uvedenému níže.

    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. Pomocí rozšíření !dh zobrazte informace záhlaví, jak je znázorněno níže.

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

Oddíl 6: Zobrazení informací o stromu zařízení Plug and Play

V části 6 zobrazíte informace o ukázkovém ovladači zařízení Sysvad a o tom, kde se nachází ve stromu zařízení Plug and Play.

Informace o ovladači zařízení ve stromu zařízení Plug and Play můžou být užitečné při řešení potíží. Pokud například ovladač zařízení není rezidentem ve stromu zařízení, může dojít k problému s instalací ovladače zařízení.

Další informace o rozšíření ladění uzlu zařízení najdete v tématu !devnode.

<-V hostitelském systému

  1. Pokud chcete zobrazit všechny uzly zařízení ve stromu zařízení Plug and Play, zadejte příkaz !devnode 0 1 . Spuštění tohoto příkazu může trvat minutu nebo dvě. Během této doby se ve stavové oblasti WinDbg zobrazí "*Busy".

    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. Pomocí Ctrl+F vyhledejte ve výstupu vygenerovaném název ovladače zařízení sysvad.

    Najděte dialogové okno s výrazem 'sysvad' zadaným do vyhledávacího pole.

    Položka uzlu zařízení s názvem sysvad_TabletAudioSample bude k dispozici ve výstupu !devnode pro Syvad.

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

    Všimněte si, že se zobrazí adresa pdo a adresa DevNode.

  3. !devnode 0 1 sysvad_TabletAudioSample Pomocí příkazu zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení Sysvad.

    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. Výstup zobrazený v předchozím příkazu obsahuje pdo přidružené ke spuštěné instanci našeho ovladače, v tomto příkladu je to 0xffffe00089c575a0. Zadáním příkazu !devobj<PDO> zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení Sysvad. Použijte adresu PDO, kterou !devnode zobrazuje na vašem počítači, ne na té, která je zde zobrazená.

    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. Výstup zobrazený v příkazu !devobj obsahuje název připojeného zařízení: \Driver\sysvad_tabletaudiosample. K zobrazení informací přidružených k připojenému zařízení použijte příkaz !drvobj s bitovou maskou 2.

    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. Zadáním příkazu !devstack<PDO> zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení. Výstup zobrazený v příkazu !devnode 0 1 obsahuje adresu PDO přidruženou ke spuštěné instanci našeho ovladače. V tomto příkladu je 0xffffe00089c575a0. Použijte adresu PDO, kterou !devnode zobrazuje na vašem počítači, ne na obrázku uvedeném níže.

    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"
    

Výstup ukazuje, že máme poměrně jednoduchý zásobník ovladačů zařízení. Ovladač sysvad_TabletAudioSample je podřízeným uzlem PnPManager. PnPManager je kořenový uzel.

Tento diagram znázorňuje složitější strom uzlů zařízení.

Diagram stromu uzlů zařízení, který se skládá z přibližně 20 uzlů

Poznámka Další informace o složitějších zásobníkech ovladačů najdete v tématu Zásobníky ovladačů a uzly zařízení a zásobníky zařízení.

Oddíl 7: Práce se zarážkou

V kapitole 7 budete pracovat se body zarážek, abyste zastavili provádění kódu v konkrétních bodech.

Nastavení zarážek pomocí příkazů

Zarážky se používají k zastavení provádění kódu na konkrétním řádku kódu. Pak můžete přejít vpřed v kódu od tohoto okamžiku a ladit tuto konkrétní část kódu.

Pro nastavení zarážky pomocí příkazu ladění použijte jeden z následujících příkazů b.

Bp

Nastaví zarážku, která bude aktivní, dokud se modul nevyloží.

Bu

Nastaví zarážku, která se nevyřeší, když se modul uvolní a znovu povolí při opětovném načtení modulu.

Bm

Nastaví zarážku pro symbol. Tento příkaz použije bu nebo bp správně a umožní použití zástupných znaků * k nastavení zarážek u všech symbolů, které odpovídají (jako všechny metody ve třídě).

  1. Pomocí uživatelského rozhraní WinDbg ověřte, že je v aktuální relaci WinDbg povolený ladicí>režim zdroje.

  2. Umístění místního kódu přidejte do zdrojové cesty zadáním následujícího příkazu.

    .sympath+ C:\WDK_Samples\Sysvad
    
  3. Přidejte umístění místního symbolu do cesty symbolu zadáním následujícího příkazu.

    .sympath+ C:\WDK_Samples\Sysvad
    
  4. Nastavte masku ladění

    Když pracujete s ovladačem, může být užitečné zobrazit všechny zprávy, které se můžou zobrazit. Zadáním následujícího příkazu změňte výchozí masku bitu ladění tak, aby se v ladicím programu zobrazily všechny zprávy ladění z cílového systému.

    0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
    
  5. Pomocí příkazu bm nastavte zarážku pomocí názvu ovladače a za ní název funkce (AddDevice), kde chcete nastavit zarážku oddělenou vykřičníkem.

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

    Můžete použít různou syntaxi ve spojení s nastavením proměnných, jako je <modul>!<symbol>, <class>::<method>, '<file.cpp>:<číslo řádku>' nebo přeskočit určitý počet <podmínek><#>. Další informace naleznete v tématu Použití přerušovacích bodů.

  6. Vypište aktuální zarážky, abyste potvrdili, že zarážka byla nastavena zadáním příkazu bl.

    0: kd> bl
    1 e fffff801`14b5f000     0001 (0001) tabletaudiosample!AddDevice
    
  7. Spuštění kódu v cílovém systému restartujte zadáním příkazu go g.

  8. ->V cílovém systému

    Ve Windows otevřete Správce zařízení pomocí ikony nebo zadáním mmc devmgmt.msc. Ve Správci zařízení rozbalte uzel Řadiče zvuku, videa a her . Vyberte a podržte položku virtuálního zvukového ovladače (nebo na to klikněte pravým tlačítkem myši) a v nabídce vyberte Zakázat .

  9. Znovu vyberte a podržte položku virtuálního zvukového ovladače (nebo na to klikněte pravým tlačítkem myši) a v nabídce vyberte Povolit .

  10. <– na hostitelském systému

    Mělo by to způsobit, že systém Windows znovu načte ovladač, který volá AddDevice. To způsobí, že se aktivuje zarážka ladění AddDevice a spuštění kódu ovladače v cílovém systému by se mělo zastavit.

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

    Pokud je cesta ke zdroji správně nastavená, měli byste se zastavit v rutině AddDevice v souboru 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. Krok po řádku kódu zadáním příkazu p nebo stisknutím klávesy F10. Můžete přejít z kódu Sysvad AddDevice na PpvUtilCall, PnpCallAddDevice a pak do kódu PipCallDriverAddDevice systému Windows. Zadáním čísla příkazu p můžete krokovat více řádků, například p 5.

  12. Po dokončení procházení kódu pomocí příkazu go g restartujte spuštění v cílovém systému.

Nastavení zarážek přístupu k paměti

Můžete také nastavit body přerušení, které se aktivují při přístupu k umístění paměti. Použijte příkaz ba (break on access) s následující syntaxí.

ba <access> <size> <address> {options}
Možnost Popis

e

provést (když procesor načte instrukci z adresy)

r

čtení/zápis (když procesor čte nebo zapisuje na adresu)

w

zapsat (když CPU zapisuje na adresu)

Mějte na paměti, že v daném okamžiku můžete nastavit pouze čtyři datové zarážky a je na vás, abyste měli jistotu, že data správně zarovnáte, jinak se zarážka nespustí (slova musí končit na adresách dělitelných dvěma, dwords musí být dělitelné čtyřmi a quadwords nulou nebo osmi).

Pokud například chcete nastavit zarážku pro čtení a zápis na konkrétní adresu paměti, použijte podobný příkaz.

ba r 4 fffff800`7bc9eff0

Úprava stavu zarážky

Existující zarážky můžete upravit pomocí následujících příkazů.

Bl

Vypíše body přerušení.

Bc

Odstraní zarážku ze seznamu. Pomocí příkazu bc * vymažte všechny zarážky.

Bd

Zakáže bod přerušení. Pomocí příkazu bd * zakažte všechny zarážky.

být

Povolí bod přerušení. Chcete-li povolit všechny zarážky, použijte příkaz *.

Případně můžete také upravit zarážky, když vyberete možnost upravit>zarážky. Všimněte si, že dialogové okno zarážky funguje pouze s existujícími zarážkami. Nové breakpointy musí být nastaveny z příkazového řádku.

Nastavte zarážku na MixerVolume

Po načtení ovladače zařízení se volá různé části kódu zvukového ovladače, aby reagovaly na různé události. V další části nastavíme zarážku, která se aktivuje, když uživatel upraví ovládací prvek hlasitosti virtuálního zvukového ovladače.

Pokud chcete nastavit breakpoint na MixerVolume, proveďte následující kroky.

  1. <– na hostitelském systému

    Chcete-li najít metodu, která změní svazek, použijte příkaz x k výpisu symbolů v CAdapterCommon, které obsahují svazek řetězce.

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

    Pomocí kombinace kláves CTRL+F vyhledejte ve výstupu hlasitosti a vyhledejte metodu MixerVolumeWrite.

  2. Pomocí bc *vymažte předchozí zarážky.

  3. Nastavte symbolickou zarážku na rutině CAdapterCommon::MixerVolumeWrite pomocí následujícího příkazu.

    kd> bm tabletaudiosample!CAdapterCommon::MixerVolumeWrite
      1: fffff801`177b26a0 @!"tabletaudiosample!CAdapterCommon::MixerVolumeWrite"
    
  4. Seznam zarážek, aby se potvrdilo, že je zarážka správně nastavena.

    kd> bl
    1 e fffff801`177b26a0 [c:\WDK_Samples\audio\sysvad\common.cpp @ 1668]    0001 (0001) tabletaudiosample!CAdapterCommon::MixerVolumeWrite
    
  5. Spuštění kódu v cílovém systému restartujte zadáním příkazu go g.

  6. V Ovládacích panelech vyberte Hardware a zvuk>Zvuk. Vyberte a podržte (nebo klikněte pravým tlačítkem myši) Ukázka popisu jímky a vyberte Vlastnosti. Vyberte kartu Úrovně . Upravte hlasitost posuvníku.

  7. To by mělo způsobit zastavení zarážky ladění SetMixerVolume a spuštění kódu ovladače v cílovém systému.

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

    Na tomto řádku byste měli přestat v common.cpp

    {
        if (m_pHW)
        {
            m_pHW->SetMixerVolume(Index, Channel, Value);
        }
    } // MixerVolumeWrite
    
  8. Pomocí příkazu dv zobrazte aktuální proměnné a jejich hodnoty. Další informace o proměnných najdete v další části tohoto cvičení.

    2: kd> dv
               this = 0x00000000`00000010
             ulNode = 0x344
          ulChannel = 0x210a45f8
            lVolume = 0n24
    
  9. Stisknutím klávesy F10 můžete procházet kódem.

  10. Stisknutím klávesy F5 dokončete provádění kódu MixerVolumeWrite.

Souhrn – krokování kódu z příkazového okna ladicího programu

Tady jsou příkazy, které můžete použít k procházení kódu (s přidruženými zkratkami klávesnice zobrazenými v závorkách).

  • Přerušení (Ctrl+Break) – Tento příkaz přeruší systém, pokud je systém spuštěný a komunikuje s WinDbg (sekvence v ladicím programu jádra je Ctrl+C).

  • Krok nad (F10) – Tento příkaz způsobí, že provádění kódu bude pokračovat jedním příkazem nebo jednou instrukcí najednou. Pokud dojde k volání, provádění kódu přeskočí volání, aniž by vstoupilo do volané rutiny. (Pokud je programovací jazyk C nebo C++ a WinDbg je ve zdrojovém režimu, můžete zdrojový režim zapnout nebo vypnout pomocí ladění>.Zdrojový režim).

  • Krok v (F11) – tento příkaz je podobný krokování, s tím rozdílem, že provádění volání přejde do volané rutiny.

  • Krok ven (Shift+F11) – Tento příkaz způsobí, že běh programu proběhne k aktuální rutině a ukončí ji (aktuální pozici v zásobníku volání). Je to užitečné, pokud už máte dost rutiny.

  • Spuštění kurzoru (F7 nebo Ctrl+F10) – umístěte kurzor do okna zdroje nebo zpětného překladu, kde chcete spuštění přerušit, a stiskněte klávesu F7; Spuštění kódu se spustí do tohoto bodu. Všimněte si, že pokud tok provádění kódu nedosahuje bodu označeného kurzorem (např. příkaz IF se nespustí), WinDbg se neporuší, protože spuštění kódu nedosahovalo uvedeného bodu.

  • Spuštění (F5) – Spusťte, dokud nedojde ke zjištění zarážky nebo události, jako je kontrola chyb.

Rozšířené možnosti

  • Nastavte instrukce na aktuální řádek (Ctrl+Shift+I) – Ve zdrojovém okně můžete umístit kurzor na řádek, zadat tuto klávesovou zkratku a spuštění kódu začne od tohoto okamžiku, jakmile ho necháte pokračovat (například pomocí klávesY F5 nebo F10). To je užitečné, pokud chcete opakovat sekvenci, ale vyžaduje trochu péče. Například registry a proměnné nejsou nastaveny na to, co by bylo, kdyby provádění kódu dosáhlo daného řádku přirozeně.

  • Přímé nastavení registru eip – hodnotu můžete vložit do registru eip a jakmile stisknete klávesu F5 (nebo F10, F11 atd.), zahájí se spuštění z této adresy. Podobá se nastavení instrukce na aktuální řádek určený kurzorem, s výjimkou toho, že zadáte adresu instrukce sestavení.

Procházení uživatelského rozhraní může být jednodušší než z příkazového řádku, takže se doporučuje tato metoda. V případě potřeby je možné pomocí následujících příkazů procházet zdrojový soubor na příkazovém řádku:

  • .lines – Aktivuje informace o zdrojovém řádku.

  • bp main – nastavte počáteční zarážku na začátku vašeho modulu.

  • l+t - Krokování se provede podle řádku kódu.

  • Vyberte Ladit>Režim zdroje pro vstup do režimu zdroje; samotný příkaz není dostačující.

  • l+s - Zdrojové řádky se zobrazí na příkazovém řádku.

  • g - Spusťte program, dokud nedosáhnete bodu 'main'.

  • p - Spusťte jeden zdrojový řádek.

Další informace naleznete v tématu Ladění zdrojového kódu ve WinDbg (Classic) v referenční dokumentaci k ladění.

Nastavení zarážek v kódu

Zarážku v kódu můžete nastavit přidáním DebugBreak() příkazu a opětovným sestavením projektu a opětovnou instalací ovladače. Tento bod přerušení se aktivuje při každém povolení ovladače, takže by to byla technika, která by se použila v počátečních fázích vývoje, nikoliv v produkčním kódu. Tato technika není tak flexibilní jako dynamické nastavení zarážek pomocí příkazů zarážky.

Tip: Můžete chtít zachovat kopii ovladače Sysvad s zarážkou přidanou pro další cvičení.

  1. Nastavte přerušení, ke kterému dojde při každém spuštění metody AddDevice přidáním DebugBreak() příkazu do ukázkového kódu.

    ...
        // 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. Podle všech výše popsaných kroků znovu sestavte ovladač v sadě Microsoft Visual Studio a znovu ho nainstalujte na cílový počítač. Před instalací aktualizovaného ovladače nezapomeňte odinstalovat existující ovladač.

  3. Vymažte všechny předchozí zarážky a ujistěte se, že je ladicí program připojený k cílovému počítači.

  4. Když se kód spustí a dosáhne DebugBreak příkazu, spuštění se zastaví a zobrazí se zpráva.

    KERNELBASE!DebugBreak:
    77b3b770 defe     __debugbreak
    

Oddíl 8: Zobrazení proměnných

V oddílu 8 použijete příkazy ladicího programu k zobrazení proměnných.

Může být užitečné prozkoumat proměnné při provádění kódu a ověřit, že kód funguje podle očekávání. Tato cvičení zkoumá proměnné, protože ovladač zvuku vytváří zvuk.

  1. Pomocí příkazu dv zkontrolujte proměnné národního prostředí přidružené k tabletaudiosample! CMiniportWaveRT::New*.

    kd> dv tabletaudiosample!CMiniportWaveRT::New*
    
  2. Vymazání předchozích zarážek

    bc *
    
  3. Nastavte symbolický bod přerušení pro rutinu CMiniportWaveCyclicStreamMSVAD pomocí následujícího příkazu.

    0: kd> bm tabletaudiosample!CMiniportWaveRT::NewStream
      1: fffff801`177dffc0 @!"tabletaudiosample!CMiniportWaveRT::NewStream"
    
  4. Spuštění kódu v cílovém systému restartujte zadáním příkazu go g.

  5. -> V cílovém systému

    Vyhledejte malý multimediální soubor (například zvukový soubor oznámení systému Windows s příponou souboru .wav) a vyberte soubor, který chcete přehrát. Můžete například použít Ring05.wav umístěné v adresáři Windows\Media.

  6. <– na hostitelském systému

    Při přehrávání multimediálního souboru by se měla aktivovat zarážka a provádění kódu ovladače v cílovém systému by se mělo zastavit.

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

    Okno zdrojového kódu by mělo zvýrazňovat závorku na vstupu do funkce NewStream.

    /*++
    
    Routine Description:
    
      The NewStream function creates a new instance of a logical stream 
      associated with a specified physical channel. Callers of NewStream should 
      run at IRQL PASSIVE_LEVEL.
    
    Arguments:
    
      OutStream -
    
      OuterUnknown -
    
      Pin - 
    
      Capture - 
    
      DataFormat -
    
    Return Value:
    
      NT status code.
    
    --*/
    {
    
    ...
    
  7. místní proměnné

    Názvy a hodnoty všech místních proměnných pro daný rámec můžete zobrazit zadáním příkazu dv.

    0: kd> dv
                    this = 0xffffe000`4436f8e0
               OutStream = 0xffffe000`49d2f130
            OuterUnknown = 0xffffe000`4436fa30
                     Pin = 0
                 Capture = 0x01 '
              DataFormat = 0xffffe000`44227790
    signalProcessingMode = {487E9220-E000-FFFF-30F1-D24900E0FFFF}
                ntStatus = 0n1055
                  stream = 0x00000000`00000200
    
  8. Zobrazení proměnných pomocí DML

    Pokud chcete použít DML k prozkoumání proměnných, vyberte podtržené prvky. Akce select vytvoří příkaz dx (Display NatVis Expression), který umožňuje přejít k podrobnostem o vnořených datových strukturách.

    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. Globální proměnné

    Umístění paměti globální proměnné najdete zadáním příkazu ? <název> proměnné.

    0: kd> ? signalProcessingMode
    Evaluate expression: -52768896396472 = ffffd001`c8acd348
    
  10. Vrátí umístění paměti proměnné, v tomto případě ffffd001'c8acd348. Obsah umístění paměti můžete zobrazit vypsáním hodnoty tohoto umístění příkazem dd s použitím umístění paměti vráceného předchozím příkazem.

    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. Názvy proměnných můžete použít také pomocí příkazu 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. Zobrazení proměnných

    K zobrazení místních proměnných použijte položku nabídky Zobrazit>místní hodnoty. Toto rozhraní také umožňuje přejít k podrobnostem o složitějších datových strukturách.

    Rozhraní WinDbg zobrazující místní prostředí vzorového kódu a okna příkazů

  13. Pomocí p nebo F10 přejděte dopředu o 10 řádků v kódu, dokud nezvýrazníte ntStatus = IsFormatSupported(Pin, Capture, DataFormat); řádek kódu.

        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. Pomocí příkazu dv zobrazíte názvy a hodnoty všech místních proměnných pro daný rámec. Všimněte si, že podle očekávání se hodnoty liší od posledního spuštění tohoto příkazu, protože se spustil další kód, který změnil místní proměnné a některé proměnné se teď v aktuálním rámci nezměnily nebo se změnily jejich hodnoty.

    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
    

Oddíl 9: Zobrazení zásobníků volání

V sekci 9 zobrazíte zásobníky volání, abyste prozkoumali kód volajícího a volaného.

Zásobník volání je řada volání funkcí, které vedly k aktuální pozici čítače programu. Horní funkce v zásobníku volání je aktuální funkce a další funkce je funkce, která volala aktuální funkci atd.

K zobrazení zásobníku volání použijte příkazy "k*":

kB

Zobrazí zásobník a první tři parametry.

Kp

Zobrazí zásobníky a úplný seznam parametrů.

kn

Umožňuje zobrazit zásobník s informacemi o zásobníkovém rámci vedle něj.

Pokud chcete mít zásobník volání k dispozici, můžete ho zobrazit výběrem Zobrazit>zásobník volání. Výběrem sloupců v horní části okna přepněte zobrazení dalších informací.

Rozhraní WinDbg zobrazující okno zásobníku volání

Tento výstup ukazuje zásobník volání při ladění ukázkového kódu adaptéru ve stavu přerušení.

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

DML můžete použít k dalšímu prozkoumání kódu. Když vyberete první položku 00, použije se k nastavení kontextu příkaz .frame (Nastavit místní kontext) a příkaz dv (Zobrazit místní proměnné) zobrazí místní proměnné.

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

Oddíl 10: Zobrazení procesů a vláken

V oddílu 10 použijete příkazy ladicího programu k zobrazení procesů a vláken.

Proces

Pokud chcete změnit kontext aktuálního procesu, použijte příkaz .process process<>. Následující příklad ukazuje, jak identifikovat proces a přepnout kontext na něj.

  • !process Pomocí příkazu zobrazíte aktuální proces, který je součástí přehrávání zvuku.

    Další informace naleznete v tématu !process

Výstup ukazuje, že proces je přidružený k audiodg.exe. Pokud jste stále na bodu přerušení popsaném v předchozí části tohoto tématu, aktuální proces by měl být přidružený k obrazu audiodg.exe.

<– na hostitelském systému

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

Všimněte si, že jedno z vláken přidružených k tomuto procesu je ve stavu SPUŠTĚNO. Toto vlákno podporovalo přehrávání mediálního klipu, když byl zasažen zarážkový bod.

Pomocí příkazu !process 0 0 zobrazíte souhrnné informace pro všechny procesy. Ve výstupu příkazu pomocí kombinace kláves CTRL+F vyhledejte ID procesu přidruženého k audiodg.exe obrázku. V následujícím příkladu je ID procesu ffffe001d147c840.

Poznamenejte si ID procesu přidružené k audiodg.exe na počítači, abyste ho mohli použít později v tomto cvičení. ________________________

...

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

Zadáním g do ladicího programu spusťte kód dopředu, dokud se nepřehraje multimediální klip. Potom přejděte do ladicího programu stisknutím kombinace kláves Ctrl+ScrLk (Ctrl+Break) Pomocí příkazu !process potvrďte, že teď spouštíte jiný proces.

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

Výše uvedený výstup ukazuje, že je spuštěn jiný systémový proces ffffe001cd0ad040 . Název obrázku zobrazuje "System", nikoli "audiodg.exe".

Nyní pomocí příkazu !process přepněte na proces, který byl přidružen k audiodg.exe. V tomto příkladu je ID procesu ffffe001d147c840. Nahraďte ID procesu v příkladu tím, které jste si poznamenali dříve.

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.

Vzhledem k tomu, že tento kód není aktivní, jsou všechna vlákna ve stavu ČEKÁNÍ podle očekávání.

Vlákna

Příkazy pro zobrazení a nastavení vláken jsou velmi podobné příkazům procesů. K zobrazení vláken použijte příkaz !thread . K nastavení aktuálních vláken použijte .thread .

Pokud chcete prozkoumat vlákna přidružená k přehrávači médií, přehrajte multimediální klip znovu. Pokud je zarážka popsaná v předchozí části stále na místě, zastavíte se v kontextu audiodg.exe.

Pomocí funkce !thread -1 0 zobrazíte stručné informace pro aktuální vlákno. Zobrazí se adresa vlákna, ID vlákna a procesu, adresa bloku prostředí vlákna (TEB), adresa funkce Win32 (pokud existuje) vlákno, které bylo vytvořeno ke spuštění, a stav plánování vlákna.

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

Pokud chcete zobrazit další informace o spuštěném vlákně, zadejte !thread. Měly by se zobrazit informace podobné následujícímu.

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

Pomocí příkazu k zobrazte zásobník volání přidružený k vláknu.

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

Zadáním g do ladicího programu spusťte kód dopředu, dokud se nepřehraje multimediální klip. Potom přejděte do ladicího programu stisknutím kláves Ctrl - ScrLk (Ctrl-Break) Pomocí příkazu !thread potvrďte, že teď používáte jiné vlákno.

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

Název obrázku je rundll32.exe, což ve skutečnosti není název obrázku přidružený k přehrávání multimediálního klipu.

Poznámka Chcete-li nastavit aktuální vlákno, zadejte číslo< vlákna .thread>.

Další informace o vláknech a procesech viz následující reference.

Vlákna a procesy

Změna kontextů

Oddíl 11: IRQL, registry a demontáž

Zobrazit uložený IRQL

V oddílu 11 zobrazíte IRQL a obsah regsisterů.

<– na hostitelském systému

Úroveň žádosti o přerušení (IRQL) se používá ke správě priority údržby přerušení. Každý procesor má nastavení IRQL, které vlákna mohou zvýšit nebo snížit. Přerušení, ke kterým dochází v nastavení IRQL procesoru nebo pod tímto nastavením, se maskují a nebudou rušit aktuální operaci. Přerušení, ke kterému dochází nad nastavením IRQL procesoru, má přednost před aktuální operací. Rozšíření !irql zobrazí úroveň žádosti o přerušení (IRQL) na aktuálním procesoru cílového počítače před přerušením ladicího programu. Když cílový počítač přejde do ladicího programu, IRQL se změní, ale IRQL, který byl aktivní těsně před přechodem do ladicího programu, se uloží a zobrazí pomocí !irql.

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

< Zobrazení registrů a demontáže

Zobrazení registrů

Pomocí příkazu r (Registers) zobrazte obsah registrů pro aktuální vlákno aktuálního procesoru.

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

Obsah registrů můžete zobrazit také tak, že vyberete Zobrazení>Registrů.

Snímek obrazovky s oknem Registrů WinDbg zobrazující přibližně 12 registrů

Zobrazení obsahu registrů může být užitečné při procházení provádění kódu jazyka sestavení a v jiných scénářích. Další informace viz r (registry).

Informace o obsahu registru naleznete v tématu architektura x86 a architektura x64.

Demontáž

Kód, který je spuštěný, můžete rozebrat a zobrazit sestavovací kód, který se spouští, výběrem možnosti Zobrazit>destrukce.

Snímek obrazovky okna WinDbg s disassembly kódem v jazyce assembleru.

Další informace o rozebrání assembleru naleznete v Annotated x86 Disassembly a Annotated x64 Disassembly.

Oddíl 12: Práce s pamětí

V oddílu 12 použijete příkazy ladicího programu k zobrazení obsahu paměti.

Zobrazení paměti

Možná budete muset prozkoumat paměť, abyste identifikovali problém nebo zkontrolovali proměnné, ukazatele atd. Paměť můžete zobrazit zadáním jednoho z následujících příkazů d* <adresa>.

databáze

Zobrazí data v bajtových hodnotách a znaky ASCII.

Dd

Zobrazí data jako dvojitá široká slova (4 bajty).

Du

Zobrazí data jako znaky Unicode.

Dw

Zobrazí data jako hodnoty slova (2 bajty) a znaky ASCII.

Poznámka Pokud se pokusíte zobrazit neplatnou adresu, její obsah se zobrazí jako otazníky (?).

Případně můžete zobrazit paměť výběrem možnosti Zobrazit>paměť. Přetažením formátu zobrazení můžete změnit způsob zobrazení paměti.

Snímek obrazovky s oknem zobrazení paměti WinDbg s různými možnostmi formátu zobrazení

  1. Chcete-li zobrazit data přidružená k ovládání hlasitosti, nastavte zarážku, která se aktivuje u rutiny PropertyHandlerAudioEngineVolumeLevel pomocí příkazu bm. Než nastavíme novou zarážku, vymažeme všechny předchozí zarážky pomocí bc *.

    kd> bc *
    
  2. Nastavte zarážku, která se aktivuje u rutiny PropertyHandlerAudioEngineVolumeLevel pomocí příkazu bm.

    kd> bm tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  3. Seznam zarážek, aby se potvrdilo, že je zarážka správně nastavena.

    kd> bl
      1: fffff80f`02c3a4b0 @!"tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume"
    
  4. Pro znovuspuštění kódu použijte příkaz g.

    V cílovém systému upravte hlasitost v hlavním panelu systému. To způsobí, že se zarážka aktivuje.

    Breakpoint 1 hit
    tabletaudiosample!CMiniportWaveRT::SetDeviceChannelVolume:
    fffff80f`02c3a4b0 44894c2420      mov     dword ptr [rsp+20h],r9d
    
  5. K zobrazení místních proměnných použijtepoložku místní nabídky>. Poznamenejte si aktuální hodnotu proměnné IVolume.

  6. Datový typ a aktuální hodnotu proměnné IVolume můžete zobrazit v ukázkovém kódu zadáním příkazu dt a názvu proměnné.

    kd> dt lVolume
    Local var @ 0xa011ea50 Type long
    0n-6291456
    
  7. Zarážka je dosažena při vstupu do 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. Pokuste se zobrazit hodnotu na paměťové adrese IVolume pomocí příkazu dt (Typ zobrazení)

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

    Vzhledem k tomu, že proměnná ještě není definovaná, neobsahuje informace.

  9. Stisknutím klávesy F10 přejděte vpřed na poslední řádek kódu v setDeviceChannelVolume.

        return ntStatus;
    
  10. Pomocí příkazu dt (Typ zobrazení) zobrazte hodnotu v umístění paměti IVolume.

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

    Teď, když je proměnná aktivní, se v tomto příkladu zobrazí hodnota 6291456.

  11. Můžete také zobrazit umístění paměti IVolume pomocí příkazu ? (Vyhodnocení výrazu).

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  12. Zobrazená adresa ffffb780'b7ee664 je adresa proměnné lVolume. Pomocí příkazu dd zobrazte obsah paměti v daném umístění.

    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. První čtyři bajty adresy můžete zobrazit zadáním parametru rozsahu L4.

    kd> dd ffffb780`b7eee664 l4
    ffffb780`b7eee664  ffa00000 00000018 00000000 c52d7008
    
  14. Pokud chcete zobrazit různé typy zobrazených výstupů paměti, zadejte příkazy du, da a 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  ....(...........
    

    Použijte možnost df float k zobrazení dat jako čísel s plovoucí desetinnou čárkou s jednoduchou přesností (4 bajty).

    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
    

Zápis do paměti

Podobně jako příkazy, které se používají pro čtení paměti, můžete pomocí příkazů e* změnit obsah paměti.

Příkaz Popis

ks

Řetězec ASCII (není ukončený hodnotou NULL)

Evropská unie

Řetězec Unicode (není ukončený hodnotou NULL

Ew

Wordové hodnoty (2 bajty)

eza

Řetězec ASCII ukončený hodnotou NULL

ezu

Řetězec Unicode ukončený hodnotou NULL

Eb

Bajtové hodnoty

Ed

Dvouslovné hodnoty (4 bajty)

Následující příklad ukazuje, jak přepsat paměť.

  1. Nejprve vyhledejte adresu lVolume, která se používá v ukázkovém kódu.

    kd> ? lVolume
    Evaluate expression: -79711507126684 = ffffb780`b7eee664
    
  2. Přepište adresu paměti novými znaky pomocí příkazu eb .

    kd> eb 0xffffb780`b7eee664 11 11 11 11 11
    
  3. Zobrazte umístění paměti, abyste potvrdili, že znaky byly přepsány zadáním příkazu db .

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

Případně můžete upravit obsah paměti v okně kukátka nebo místní hodnoty. V sledovacím okně se mohou zobrazit proměnné, které jsou mimo kontext aktuální snímky. Úpravy nejsou relevantní, pokud nejsou v kontextu.

Oddíl 13: Ukončení relace WinDbg

<-V hostitelském systému

Pokud chcete ponechat ladicí program připojený, ale chcete pracovat na cílovém počítači, vymažte všechny zarážky s použitím bc *, aby se cílový počítač nepokoušel připojit k ladicímu programu hostitelského počítače. Potom pomocí příkazu g nechte cílový počítač běžet znovu.

Pokud chcete ukončit ladicí relaci, na hostitelském systému přerušte ladicí program a zadejte příkaz qd (Ukončit a odpojit), nebo v nabídce vyberte Zastavit ladění.

0: kd> qd

Další informace naleznete v tématu Ukončení ladicího sezení v WinDbg (Classic) v referenční dokumentaci k ladění.

Oddíl 14: Prostředky pro ladění Windows

Další informace jsou k dispozici v ladění Systému Windows. Všimněte si, že některé z těchto knih budou používat starší verze Systému Windows, jako je Windows Vista v jejich příkladech, ale popisované koncepty platí pro většinu verzí Windows.

knihy

  • Rozšířené ladění Windows od Maria Hewardta a Daniela Pravata

  • Ladění v systému Windows: Praktický průvodce laděním a trasováním strategií ve Windows® od Tarik Soulami

  • Windows Internals od Pavel Yosifovich, Alex Ionescu, Mark Russinovich a David Solomon

Video

The Defrag Tools Show WinDbg Epizods 13-29: </shows/defrag-tools/>

Dodavatelé školení:

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

Viz také

Začínáme s laděním windows