Sdílet prostřednictvím


Podrobné cvičení ladění ovladačů systému Windows (režim jádra echo)

Tato laboratoř představuje ladicí program jádra WinDbg. WinDbg slouží k ladění ukázkového kódu ovladače režimu jádra echo.

Cíle testovacího prostředí

Tato laboratoř zahrnuje cvičení, která představují nástroje ladění, učí běžné příkazy ladění, ilustrují použití zarážek a ukazují, jak používat ladicí rozšíření.

V tomto cvičení použijete živé připojení k ladění jader ke zkoumání následujících akcí:

  • Použití příkazů ladicího programu systému Windows
  • Použijte standardní příkazy (zásobníky volání, proměnné, vlákna, IRQL)
  • Použijte pokročilé příkazy ladění ovladačů (!commands)
  • Použití symbolů
  • Nastavení zarážek v živém ladění
  • Zobrazení zásobníků volání
  • Zobrazení stromu zařízení Plug and Play
  • Práce s kontextem vlákna a procesu

Ladění uživatelského a jaderného módu

Při práci s ladicím programem systému Windows můžete provádět dva typy ladění:

uživatelský režim – aplikace a subsystémy běží v počítači v uživatelském režimu. Procesy, které běží v uživatelském režimu, to dělají ve svých vlastních virtuálních adresních prostorech. Přístup k mnoha částem systému, včetně systémového hardwaru, paměti, která není přidělena pro jejich použití, a dalších částí systému, které by mohly ohrozit integritu systému, jsou omezené. Protože procesy, které běží v uživatelském režimu, jsou efektivně izolované od systému a jiných procesů uživatelského režimu, nemůžou narušovat tyto prostředky.

režim jádra – operační systém a privilegované programy běží v režimu jádra. Kód v režimu jádra má oprávnění pro přístup k jakékoli části systému. Není omezený jako kód uživatelského režimu. Může získat přístup k jakékoli části jakéhokoli jiného procesu spuštěného v uživatelském režimu nebo v režimu jádra. Většina základních funkcí operačního systému a mnoho ovladačů hardwarových zařízení běží v režimu jádra.

Toto cvičení se zabývá příkazy ladění, které se často používají při ladění v uživatelském režimu i v režimu jádra. Toto cvičení také popisuje rozšíření ladění, někdy označovaná jako "bang" !commands, které se používají pro ladění v režimu jádra.

Nastavení testovacího prostředí

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

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

K dokončení cvičení potřebujete následující software:

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

Testovací prostředí obsahuje následující části:

Připojte se k relaci WinDbg v režimu jádra

V této části nakonfigurujte 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. Ladicí program systému Windows běží na hostitelském systému a ovladač echo frameworku KMDF (Kernel Mode Driver Framework) běží na cílovém systému .

Pomocí síťového rozbočovače nebo směrovače a síťových kabelů připojte tyto 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 (režim jádra). 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í sítě Ethernet

Pro povolení ladění režimu jádra na cílovém systému:

  1. V hostitelském systému otevřete okno příkazového řádku a zadejte ipconfig určit jeho adresu IPv4.

    Windows IP Configuration
    Ethernet adapter Ethernet:
       Connection-specific DNS Suffix  . :
       Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b%3
       Autoconfiguration IPv4 Address. . : 169.182.1.1
       Subnet Mask . . . . . . . . . . . : 255.255.0.0
       Default Gateway . . . . . . . . . :
    
  2. Záznam IP adresy hostitelského systému: ______________________________________

  3. V cílovém systému otevřete okno příkazového řádku a pomocí příkazu ping potvrďte síťové připojení mezi těmito dvěma systémy.

    ping 169.182.1.1
    

    Použijte skutečnou IP adresu hostitelského systému, který jste si poznamenali místo 169.182.1.1, která je zobrazená v ukázkovém výstupu.

    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
    

Povolte ladění v režimu jádra na cílovém systému provedením následujících kroků.

Důležitý

Než použijete BCDEdit ke změně informací o spuštění, možná budete muset 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í tyto funkce zabezpečení znovu povolte. Správně spravujte testovací počítač, když jsou zakázané funkce zabezpečení. 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. Na cílovém počítači otevřete okno příkazového řádku jako správce. Zadáním tohoto příkazu povolte ladění:

    bcdedit /set {default} DEBUG YES
    
  2. Zadáním tohoto příkazu povolíte podepisování testů:

    bcdedit /set TESTSIGNING ON 
    
  3. Zadáním tohoto příkazu nastavte IP adresu hostitelského systému. Použijte IP adresu hostitelského systému, který jste si poznamenali dříve, ne tu zobrazenou.

    bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    

    Varování

    Pro zvýšení zabezpečení připojení a snížení rizika náhodných požadavků na připojení ladicího programu klienta použijte automaticky vygenerovaný náhodný klíč. Další informace naleznete v tématu Nastavení ladění jádra sítě KDNET automaticky.

  4. Zadáním tohoto příkazu potvrďte, že jsou správně nastavené hodnoty pro dbgsettings:

    bcdedit /dbgsettings
    
    key                     2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    debugtype               NET
    hostip                  169.168.1.1
    port                    50000
    dhcp                    Yes
    The operation completed successfully.
    

    Poznámka

    Pokud obdržíte zprávu z firewallu a chcete použít ladicí program, zaškrtněte všechna tři políčka.

    snímek obrazovky s dialogovým oknem Výstraha zabezpečení systému Windows označující, že brána Windows Firewall zablokovala některé funkce aplikace.

  5. Na hostitelském počítači otevřete okno příkazového řádku jako správce. Tato laboratoř používá verzi x64 WinDbg.exe ze sady Windows Driver Kit (WDK), která byla nainstalována jako součást instalace kitu Windows. Přejděte do výchozího adresáře WinDbg, výchozí umístění je znázorněno níže.

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

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

  6. Pomocí následujícího příkazu otevřete WinDbg s vzdáleným laděním. Hodnoty klíče a portu odpovídají hodnotám, které jste nastavili dříve pomocí BCDEdit na cílovém počítači.

    WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  7. Restartujte cílový systém.

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

    Microsoft (R) Windows Debugger Version 10.0.17074.1002 AMD64
    Copyright (c) Microsoft Corporation. All rights reserved.
    
    Using NET for debugging
    Opened WinSock 2.0
    Waiting to reconnect...
    Connected to target 169.182.1.1 on port 50005 on local IP 169.182.1.2
    You can get the target MAC address by running .kdtargetmac command.
    Connected to Windows 10 16299 x64 target at (Wed Feb 28 17:16:23.051 2018 (UTC - 8:00)), ptr64 TRUE
    Kernel Debugger connection established.  (Initial Breakpoint requested)
    Symbol search path is: srv*
    Executable search path is: 
    Windows 10 Kernel Version 16299 MP (4 procs) Free x64
    Product: WinNt, suite: TerminalServer SingleUserTS
    Built by: 16299.15.amd64fre.rs3_release.170928-1534
    Machine Name:
    Kernel base = 0xfffff800`9540d000 PsLoadedModuleList = 0xfffff800`95774110
    Debug session time: Wed Feb 28 17:16:23.816 2018 (UTC - 8:00)
    System Uptime: 0 days 0:00:20.534
    

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. Zadejte příkazy do menšího podokna, což je podokno pro zadávání příkazů v dolní části okna, a zobrazte výstup příkazu ve větším podokně v horní části okna.

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

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

V této části použijte příkazy ladění k zobrazení informací o cílovém systému.

Některé ladicí příkazy zobrazují text pomocí jazyka DML (Debugger Markup Language), který můžete vybrat, abyste mohli rychle shromáždit další informace.

  1. V hostitelském systému pomocí kombinace kláves Ctrl+Scroll Lock v systému WinDBg rozdělte kód spuštěný v cílovém systému. Reakce cílového systému může nějakou dobu trvat.

    hlavní obrazovka v ladicím programu zobrazující výstup příkazového okna z živého připojení k jádru.

  2. Zadáním následujícího příkazu povolte DML v okně příkazu ladicího programu:

    0: kd> .prefer_dml 1
    DML versions of commands on by default
    
  3. Pomocí příkazu .hh můžete získat přístup k nápovědě k referenčnímu příkazu. Zadejte následující příkaz, abyste zobrazili referenční nápovědu k příkazu .prefer_dml:

    0: kd> .hh .prefer_dml
    

    Soubor nápovědy ladicího programu zobrazí nápovědu pro příkaz .prefer_dml.

    Snímek obrazovky aplikace nápovědy ladicího programu, který zobrazuje nápovědu pro příkaz .prefer-dml

  4. Pokud chcete zobrazit podrobné informace o verzi cílového systému, zadejte vertarget (Zobrazit verzi cílového počítače) příkaz 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
    
  5. Pokud chcete ověřit, že pracujete se správným procesem režimu jádra, zadejte příkaz lm (List Loaded Modules) v okně WinDbg a zobrazte načtené moduly:

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

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

  6. Chcete-li požádat o podrobné informace o konkrétním modulu, použijte možnost v (podrobné):

    0: Kd> lm v m tcpip
    Browse full module list
    start             end                 module name
    fffff801`09eeb000 fffff801`0a157000   tcpip      (no symbols)           
        Loaded symbol image file: tcpip.sys
        Image path: \SystemRoot\System32\drivers\tcpip.sys
        Image name: tcpip.sys
        Browse all global symbols  functions  data
        Timestamp:        Sun Nov 09 18:59:03 2014 (546029F7)
        CheckSum:         00263DB1
        ImageSize:        0026C000
        Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4
    
    Unable to enumerate user-mode unloaded modules, Win32 error 0n30
    

    Není nastavena cesta pro symboly a symboly nejsou načteny, takže je v ladicím programu k dispozici jen omezené množství informací.

Stažení a sestavení ovladače echo KMDF

V této části stáhněte a sestavte ovladač echo KMDF.

Obvykle byste při použití WinDbg pracovali s vlastním kódem ovladače. Abyste se seznámili s provozem WinDbg, používá tato laboratoř ukázkový ovladač Echo, který je součástí šablony KMDF. Zdrojový kód je k dispozici, aby pomohl pochopit informace, které se zobrazují v WinDbg. Tato ukázka se také používá k ilustraci toho, jak můžete jedním krokem procházet nativní kód v režimu jádra. Tato technika může být cenná pro ladění složitých problémů s kódem v režimu jádra.

Stažení a sestavení ukázkového ovladače Echo:

  1. Nejprve si stáhněte a extrahujte ukázku KMDF Echo z GitHubu.

    Ukázka služby KMDF Echo se nachází ve složce obecné složky.

    snímek obrazovky se stránkou s ukázkami windows-driver-samples GitHubu, která zvýrazňuje obecnou složku a tlačítko zip ke stažení

    1. Stáhněte si ukázky ovladačů v jednom souboru ZIP: ukázky ovladačů

    2. Stáhněte si soubor ZIP na místní pevný disk.

    3. Vyberte soubor ZIP, podržte ho nebo na něj klikněte pravým tlačítkem myši a pak vyberte Extrahovat všechny. Zadejte novou složku nebo přejděte k existující složce a uložte extrahované soubory. Můžete například zadat C:\DriverSamples\ jako novou složku, do které chcete extrahovat soubory.

    4. Po extrahování souborů přejděte do následující podsložky: C:\DriverSamples\general\echo\kmdf

  2. V Microsoft Visual Studio vyberte Soubor>Otevřít>Projekt/Řešení... a přejděte do složky, která obsahuje extrahované soubory, například C:\DriverSamples\general\echo\kmdf. Poklikejte na soubor kmdfecho řešení a otevřete ho.

    V sadě Visual Studio vyhledejte Průzkumníka řešení. Pokud toto okno již není otevřeno, z nabídky Zobrazení vyberte Průzkumník řešení. V Průzkumníku řešení uvidíte jedno řešení, které má tři projekty.

    snímek obrazovky sady Visual Studio zobrazující soubor device.c načtený z projektu kmdfecho

  3. Nastavte konfiguraci a platformu ukázky. V Průzkumníku řešení vyberte a podržte nebo klikněte pravým tlačítkem na Řešení 'kmdfecho' (3 projekty)a vyberte Správce konfigurace. Ujistěte se, že jsou pro tři projekty stejná nastavení konfigurace a platformy. Ve výchozím nastavení je konfigurace pro všechny projekty nastavena na Win10 Debuga platforma na Win64. Pokud provedete jakékoli změny konfigurace nebo platformy pro jeden projekt, proveďte stejné změny u zbývajících tří projektů.

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

  5. Nastavte knihovnu modulu runtime. Otevřete stránku vlastností ovladače echo a vyhledejte >C/C++ Generování kódu. Změňte knihovnu modulu runtime na vícevláknové ladění (/MTd). Další informace o možnostech sestavení najdete v tématu /MD, /MT, /LD (použijte knihovnu Run-Time).

    Snímek obrazovky stránky vlastností echo v programu Visual Studio s vyznačením nastavení knihovny modulu runtime.

  6. Ve vlastnostech ovladače se ujistěte, že je Podepisování ovladačů>režim podepisování nastaven na Testovací podepisování.

    Snímek obrazovky na stránce vlastností Echo v sadě Visual Studio se zvýrazněným nastavením režimu podepisování

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

    V oknech sestavení by se měla zobrazit zpráva, že sestavení pro všechny tři projekty bylo úspěšné.

Spropitné

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. V Průzkumníku souborů přejděte do složky, která obsahuje extrahované soubory pro ukázku. Například přejděte na C:\DriverSamples\general\echo\kmdf, 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 ponecháli výchozí nastavení beze změny, kompilované soubory ovladačů se uloží do složky s názvem \x64\Debug pro 64bitové sestavení ladění.

    Přejděte do složky, která obsahuje vytvořené soubory pro ovladač automatické synchronizace: C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.

    Složka by měla obsahovat tyto soubory:

    Soubor Popis
    Echo.sys Soubor ovladače.
    Echo.inf Informační soubor (INF), který obsahuje informace potřebné k instalaci ovladače.

    Také byl vytvořen soubor echoapp.exe a měl by být umístěn zde: C:\DriverSamples\general\echo\kmdf\exe\x64\Debug.

    Soubor Popis
    EchoApp.exe Spustitelný testovací soubor příkazového řádku, který komunikuje s ovladačem echo.sys.
  2. Najděte USB flash disk nebo nastavte sdílenou síťovou složku pro zkopírování souborů vytvořených ovladačů a testu EchoApp z hostitelského do cílového systému.

V další části zkopírujte kód do cílového systému a nainstalujte a otestujte ovladač.

Instalace ukázkového ovladače typu echo KMDF na cílový systém

V této části použijte nástroj DevCon k instalaci ukázkového ovladače echo.

Počítač, do kterého ovladač instalujete, se nazývá cílovým počítačem nebo testovacím počítačem. Tento počítač je obvykle oddělený 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.

Před nasazením testovacího podepsaného ovladače připravte cílový počítač povolením podepisování testů. Musíte také vyhledat nástroj DevCon v instalaci WDK a zkopírovat ho do cílového systému.

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

V cílovém systému povolte testem podepsané ovladače.

  1. Otevřete Nastavení systému 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 možnosti spuštění. Ve Windows 10 vyberte Poradce při potížích>Rozšířené možnosti>Nastavení spouštění a pak vyberte Restartovat.

  5. Pomocí klávesy F7 vyberte Zakázat ověřování podpisu ovladače.

  6. Restartujte cílový počítač.

V hostitelském systému přejděte do složky Tools v instalaci WDK a vyhledejte nástroj DevCon. Například vyhledejte následující složku: C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe.

Vytvořte složku v cíli pro sestavený balíček ovladačů, například C:\EchoDriver. Zkopírujte devcon.exe do cílového systému. Vyhledejte certifikát .cer v hostitelském systému. Je ve stejné složce na hostitelském počítači ve složce, která obsahuje vytvořené soubory ovladačů. Zkopírujte všechny soubory z vytvořeného ovladače popsaného výše na hostitelském počítači a uložte je do stejné složky, kterou jste vytvořili v cílovém počítači.

Na cílovém počítači vyberte a podržte soubor certifikátu nebo na soubor certifikátu klikněte pravým tlačítkem myši a vyberte Nainstalovata pak podle pokynů nainstalujte testovací certifikát.

Pokud potřebujete podrobnější pokyny k nastavení cílového počítače, přečtěte si téma Příprava počítače pro ruční nasazení ovladačů.

Následující pokyny ukazují, jak nainstalovat a otestovat ukázkový ovladač. Tady je obecná syntaxe nástroje devcon, který používáte k instalaci ovladače:

devcon install <INF file> <hardware ID>

Soubor INF vyžadovaný pro instalaci tohoto ovladače je echo.inf. Soubor inf obsahuje ID hardwaru pro instalaci echo.sys. Pro vzorek ozvěny je ID hardwaru root\ECHO.

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 a zadejte následující příkaz:

devcon install echo.inf root\ECHO

Pokud se zobrazí chybová zpráva, že devcon není rozpoznán, zkuste přidat cestu k nástroji devcon. Pokud jste ho například zkopírovali do složky s názvem C:\Tools, zkuste použít následující příkaz:

c:\tools\devcon install echo.inf root\ECHO

Zobrazí se dialogové okno, které označuje, ž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 softwaru ovladače.

Rady

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

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

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 zvolte Zařízení podle typu. Ve stromu zařízení vyhledejte Ukázkový ovladač WDF Echo Driver v uzlu Ukázkové zařízení.

snímek obrazovky se stromem Správce zařízení se zvýrazněním ukázkového ovladače ozvěny WDF

Zadáním echoapp spusťte aplikaci testovací odezvy a ověřte, že je ovladač funkční.

C:\Samples\KMDF_Echo_Sample> echoapp
DevicePath: \\?\root#sample#0005#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
Opened device successfully
512 Pattern Bytes Written successfully
512 Pattern Bytes Read successfully
Pattern Verified successfully
30720 Pattern Bytes Written successfully
30720 Pattern Bytes Read successfully
Pattern Verified successfully

Zobrazení informací o ovladači pomocí WinDbg

V této části nastavte cestu symbolu a pomocí příkazů ladicího programu jádra zobrazte informace o ukázkovém ovladači odezvy KMDF.

Zobrazení informací o ovladači:

  1. Pokud jste ladicí program zavřeli v hostitelském systému, otevřete ho znovu pomocí následujícího příkazu v okně příkazového řádku správce.

    WinDbg -k net:port=50000,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.

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

    0: kd> .symfix
    
  4. 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:\DriverSamples\general\echo\kmdf
    0: kd> .reload /f
    

    Příkaz .reload s možností /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.

Abyste mohli používat pokročilé funkce, které poskytuje WinDbg, musíte načíst správné symboly. Pokud nemáte správně nakonfigurované symboly, při pokusu o použití funkcí závislých na symbolech se zobrazí zprávy, které označují, že symboly nejsou dostupné.

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

Existuje mnoho 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. Tato laboratoř používá tento přístup. 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 k symbolům pro ladicí program systému Windows.

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ů (.pdb soubory). Tyto soubory symbolů ukazují debuggeru, 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. Pro ladění je nejlepší, pokud 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 oblasti příkazů ladicího programu zadejte následující příkaz, který zobrazí informace o ovladači echo:

    0: kd> lm m echo* v
    Browse full module list
    start             end                 module name
    fffff801`4ae80000 fffff801`4ae89000   ECHO       (private pdb symbols)  C:\Samples\KMDF_ECHO_SAMPLE\echo.pdb
        Loaded symbol image file: ECHO.sys
        Image path: \SystemRoot\system32\DRIVERS\ECHO.sys
        Image name: ECHO.sys
    ...  
    

    Další informace naleznete na stránce lm.

  2. Vzhledem k tomu, že laboratorní sada prefer_dml byla nastavena dříve, jsou některé prvky výstupu aktivními odkazy, které můžete vybrat. Vyberte odkaz Procházet všechny globální symboly ve výstupu z ladění, aby se zobrazily informace o symbolech, které začínají na písmeno "a".

    0: kd> x /D Echo!a*
    
  3. Ukázka ozvěny neobsahuje žádné symboly, které začínají písmenem "a", takže zadejte x ECHO!Echo*, aby se zobrazily informace o všech symbolech spojených s ovladačem echo, který začíná na "Echo".

    0: kd> x ECHO!Echo*
    fffff801`0bf95690 ECHO!EchoEvtIoQueueContextDestroy (void *)
    fffff801`0bf95000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *)
    fffff801`0bf95ac0 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *)
    fffff801`0bf9b120 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *)
    ...
    

    Další informace najdete v x (Prozkoumat symboly).

  4. Rozšíření !lmi zobrazuje podrobné informace o modulu. Zadejte !lmi echo. Výstup by se měl podobat textu uvedenému v tomto příkladu:

    0: kd> !lmi echo
    Loaded Module Info: [echo] 
             Module: ECHO
       Base Address: fffff8010bf94000
         Image Name: ECHO.sys
    … 
    
  5. Pomocí rozšíření !dh zobrazte informace záhlaví, jak je znázorněno v tomto příkladu:

    0: kd> !dh echo
    
    File Type: EXECUTABLE IMAGE
    FILE HEADER VALUES
         14C machine (i386)
           6 number of sections
    54AD8A42 time date stamp Wed Jan 07 11:34:26 2015
    ...
    
  6. Zadáním následujícího příkazu změňte výchozí bitovou masku debugu tak, aby se všechny debug zprávy z cílového systému zobrazovaly v debugovacím rozhraní:

    0: kd> ed nt!Kd_DEFAULT_MASK 0xFFFFFFFF
    

    Některé ovladače zobrazují další informace při použití masky 0xFFFFFFFF. Pokud chcete snížit množství zobrazených informací, nastavte masku na 0x00000000.

    0: kd> ed nt!Kd_DEFAULT_MASK 0x00000000
    

    Pomocí příkazu dd potvrďte, že je maska nastavena tak, aby zobrazovala všechny debuggerové zprávy.

    0: kd> dd nt!kd_DEFAULT_MASK 
    fffff802`bb4057c0  ffffffff 00000000 00000000 00000000
    fffff802`bb4057d0  00000000 00000000 00000000 00000000
    fffff802`bb4057e0  00000001 00000000 00000000 00000000
    fffff802`bb4057f0  00000000 00000000 00000000 00000000
    fffff802`bb405800  00000000 00000000 00000000 00000000
    fffff802`bb405810  00000000 00000000 00000000 00000000
    fffff802`bb405820  00000000 00000000 00000000 00000000
    fffff802`bb405830  00000000 00000000 00000000 00000000
    

Zobrazení informací o stromu zařízení Plug and Play

V této části zobrazte informace o ukázkovém ovladači zařízení echo a jeho umístění 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.

  1. Pokud chcete v hostitelském systému zobrazit všechny uzly zařízení ve stromu zařízení Plug and Play, zadejte příkaz !devnode 0 1.

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

    snímek obrazovky s dialogovým oknem Najít ve WinDbg, ve které hledáte výraz echo.

  3. Ovladač zařízení echo by měl být načten. Pomocí příkazu !devnode 0 1 echo zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení echo, jak je znázorněno v tomto příkladu:

    0: Kd> !devnode 0 1 echo
    Dumping IopRootDeviceNode (= 0xffffe0007b725d30)
    DevNode 0xffffe0007b71a630 for PDO 0xffffe0007b71a960
      InstancePath is "ROOT\SAMPLE\0000"
      ServiceName is "ECHO"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
    …
    
  4. Výstup zobrazený v předchozím příkazu obsahuje PDO přidružené ke spuštěné instanci vašeho ovladače, zde v příkladu 0xffffe0007b71a960. Zadáním příkazu !devobj <PDO address> zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení echo. Použijte adresu PDO, kterou zobrazuje !devnode na vašem počítači, ne tu adresu zobrazenou zde.

    0: kd> !devobj 0xffffe0007b71a960
    Device object (ffffe0007b71a960) is for:
     0000000e \Driver\PnpManager DriverObject ffffe0007b727e60
    Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001040
    Dacl ffffc102c9b36031 DevExt 00000000 DevObjExt ffffe0007b71aab0 DevNode ffffe0007b71a630 
    ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
    Characteristics (0x00000180)  FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
    AttachedDevice (Upper) ffffe000801fee20 \Driver\ECHO
    Device queue is not busy.
    
  5. Výstup zobrazený v příkazu !devnode 0 1 obsahuje adresu PDO přidruženou ke spuštěné instanci ovladače, v tomto příkladu je to 0xffffe0007b71a960. Zadáním příkazu !devstack <PDO address> zobrazte informace o modulu Plug and Play přidružené k ovladači zařízení. Použijte adresu PDO, kterou !devnode zobrazuje na vašem počítači, nikoli adresu zobrazenou v tomto příkladu.

    0: kd> !devstack 0xffffe0007b71a960
      !DevObj           !DrvObj            !DevExt           ObjectName
      ffffe000801fee20  \Driver\ECHO       ffffe0007f72eff0  
    > ffffe0007b71a960  \Driver\PnpManager 00000000  0000000e
    !DevNode ffffe0007b71a630 :
      DeviceInst is "ROOT\SAMPLE\0000"
      ServiceName is "ECHO"
    

Výstup ukazuje, že máte poměrně jednoduchou sadu ovladačů zařízení. Ovladač echo je podřízeným uzlem PnPManager. PnPManager je kořenový uzel.

\Driver\ECHO
\Driver\PnpManager

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

diagram znázorňující strom uzlů zařízení, který se skládá z přibližně 20 uzlů.

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

Práce se zarážkami a zdrojovým kódem

V této části nastavte zarážky a procházejte zdrojový kód v režimu jádra po jednotlivých krocích.

Abyste mohli procházet kód a kontrolovat hodnoty proměnných v reálném čase, povolte zarážky a nastavte cestu ke zdrojovému kódu.

Zarážky zastavují provádění kódu na konkrétním řádku kódu. Krokujte dále v kódu od tohoto bodu a debugujte specifickou část kódu.

Pokud chcete nastavit zarážku pomocí příkazu ladění, použijte jeden z následujících příkazů b.

Příkaz Popis
bp Nastaví zarážku, která je aktivní, dokud se modul nenačte.
bu Nastaví zarážku, která zůstane nevyřešená, když je modul uvolněn, a znovu se aktivuje při opětovném načtení modulu.
bm Nastaví zarážku pro symbol. Tento příkaz používá bu nebo bp odpovídajícím způsobem a umožňuje použití zástupných znaků (*) k nastavení zarážek u každého symbolu, který odpovídá, stejně jako všechny metody ve třídě.

Další informace naleznete v tématu Ladění zdrojového kódu v winDbg.

  1. V hostitelském systému pomocí uživatelského rozhraní WinDbg ověřte, že v aktuální relaci WinDbg je povolen režim Ladění>Zdroj.

  2. Zadejte následující příkaz, který přidá umístění místního kódu do zdrojové cesty:

    .srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  3. Zadejte následující příkaz, abyste přidali místní umístění symbolu do cesty k symbolu.

    .sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  4. Pomocí příkazu x zkontrolujte symboly přidružené k ovladači echo a určete název funkce, který se má použít pro zarážku. K vyhledání názvu DeviceAdd funkce můžete použít zástupný znak nebo Ctrl+F.

    0: kd> x ECHO!EchoEvt*
    8b4c7490          ECHO!EchoEvtIoQueueContextDestroy (void *)
    8b4c7000          ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *)
    8b4c7820          ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *)
    8b4cb0e0          ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *)
    8b4c75d0          ECHO!EchoEvtIoWrite (struct WDFQUEUE__ *, struct WDFREQUEST__ *, unsigned int)
    8b4cb170          ECHO!EchoEvtDeviceAdd (struct WDFDRIVER__ *, struct 
    …
    

    Výstup ukazuje, že DeviceAdd metoda pro ovladač echo je ECHO!EchoEvtDeviceAdd.

    Můžete také zkontrolovat zdrojový kód a vyhledat název funkce pro váš bod přerušení.

  5. Nastavte zarážku pomocí příkazu bm pomocí názvu ovladače, za kterým následuje název funkce, například AddDevice, kde chcete nastavit zarážku oddělenou vykřičníkem. Tato laboratoř používá AddDevice ke sledování načítání ovladače.

    0: kd> bm ECHO!EchoEvtDeviceAdd
      1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
    

    ** Můžete použít různou syntaxi ve spojení s nastavením proměnných, jako jsou <module>!<symbol>, <class>::<method>,'<file.cpp>:<line number>', nebo přeskočit určitý početkrát <condition> <#>. Další informace naleznete v tématu Podmíněné zarážky v WinDbg a dalších ladicích programech systému Windows.

  6. Zadáním příkazu bl zobrazte seznam aktuálních zarážek a potvrďte, že byla zarážka nastavená:

    0: kd> bl
    1 e fffff801`0bf9b1c0     0001 (0001) ECHO!EchoEvtDeviceAdd
    

    "e" ve zde zobrazeném výstupu znamená, že zarážka číslo 1 je aktivována k odpálení.

  7. Restartujte provádění kódu v cílovém systému zadáním příkazu g (go).

  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 Ukázky.

  9. Vyberte a podržte nebo klikněte pravým tlačítkem myši na položku ovladače KMDF Echo a v nabídce vyberte Zakázat.

  10. Znovu vyberte a podržte položku KMDF echo driver nebo na ni klepněte pravým tlačítkem myši a v nabídce vyberte Povolit.

  11. Pokud je ovladač v hostitelském systému povolený, měl by se aktivovat AddDevice zarážku ladění. Spuštění kódu ovladače v cílovém systému by se mělo zastavit. Po dosažení zarážky by mělo být spuštění zastaveno na začátku rutiny AddDevice. Výstup příkazu ladění zobrazí Breakpoint 1 hit.

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

  12. Krokujte řádek kódu po řádku zadáním příkazu p nebo stisknutím klávesy F10, dokud nedosáhnete následujícího konce rutiny AddDevice. Znak mřížky (}) je zvýrazněn, jak je znázorněno.

    Snímek obrazovky okna kódu se zvýrazněnou složenou závorkou na začátku rutiny AddDevice.

V další části zkontrolujte stav proměnných po spuštění kódu DeviceAdd.

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

Příkaz Popis
bl Vypíše body přerušení.
bc Odstraní zarážku ze seznamu. Pomocí bc * vymažte všechny zarážky.
bd Zakáže zarážku. K deaktivaci všech breakpointů použijte bd *.
be Povolí bod přerušení. Pomocí be * povolte všechny zarážky.

Případně můžete také upravit zarážky v uživatelském rozhraní WinDbg.

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 execute: když procesor načte instrukce z adresy
r čtení/zápis: když CPU čte nebo zapisuje na adresu
w write: při zápisu procesoru na adresu

V daném okamžiku můžete nastavit pouze čtyři datové zarážky. Je na vás, abyste měli jistotu, že data správně zarovnáte, aby se aktivovala zarážka. Slova musí končit adresami dělitelnými 2, dvojitá slova musí být dělitelná 4 a čtyřslova musí být dělitelná 8.

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

ba r 4 0x0003f7bf0

Následující příkazy můžete použít k procházení kódu s přidruženými krátkými řezy klávesnice zobrazenými v závorkách.

  • Přerušit (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.
  • Spusťte kurzor (F7 nebo Ctrl+F10). Umístěte kurzor do okna zdroje nebo disassembleru, kde chcete spuštění přerušit, a stiskněte klávesu F7. Kód se spustí až k tomuto bodu. Pokud tok provádění kódu nedosáhne bodu označeného kurzorem, WinDbg by se nepřerušil. K této situaci může dojít v případě, že se nespustí příkaz IF.
  • Spusťte (F5). Spouštějte, dokud nedosáhnete zarážky nebo neproběhne událost, jako je například kontrola chyb.
  • Krok za krokem (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ím jazykem C nebo C++ a WinDbg je ve zdrojovém režimu, můžete tento režim zapnout nebo vypnout pomocí ladit>zdrojového režimu.
  • 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.
  • Vystupte (Shift+F11). Tento příkaz způsobí, že se provádění spustí a ukončí z aktuální rutiny nebo aktuálního místa v zásobníku volání. Tento příkaz je užitečný, pokud už máte dost rutiny.

Další informace naleznete v tématu Ladění zdrojového kódu v WinDbg.

Zobrazení proměnných a zásobníků volání

V této části zobrazte informace o proměnných a zásobnících volání.

V tomto cvičení se předpokládá, že jste zastaveni v rutině AddDevice pomocí výše popsaného procesu. Pokud chcete zobrazit zde zobrazený výstup, opakujte kroky popsané výše v případě potřeby.

Pokud chcete zobrazit proměnné v hostitelském systému, použijte k zobrazení>a vyberte místní položku nabídky pro zobrazení místních proměnných.

Snímek obrazovky WinDbg zobrazující okno místních proměnných

Pokud chcete najít umístění adresy globální proměnné, zadejte ? <variable name>.

  • Krok ven (Shift+F11) – Tento příkaz způsobí spuštění do aktuální rutiny (aktuální místo v zásobníku volání). Je to užitečné, pokud už máte dost rutiny.

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

Oddíl 8: Zobrazení proměnných a zásobníků volání

v části 8 zobrazíte informace o proměnných a zásobníkech volání.

V tomto cvičení se předpokládá, že jste zastaveni v rutině AddDevice pomocí výše popsaného procesu. Pokud chcete zobrazit výstup zde, opakujte kroky popsané výše v případě potřeby.

<– na hostitelském systému

Zobrazení proměnných

K zobrazení místních proměnných použijte zobrazení místní položky nabídky >.

Snímek obrazovky WinDbg zobrazující okno místních proměnných

Globální proměnné

Umístění globální proměnné adresy najdete zadáním ? <název proměnné>.

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. Pokud chcete zobrazit názvy a hodnoty všech místních proměnných pro určitý rámec, zadejte příkaz dv:

0: kd> dv
         Driver = 0x00001fff`7ff9c838
     DeviceInit = 0xffffd001`51978190
         status = 0n0

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

Příkaz Popis
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.
  1. Na hostitelském systému, chcete-li ponechat zásobník volání dostupný, vyberte zobrazení >zásobníku volání pro zobrazení. Výběrem sloupců v horní části okna přepněte zobrazení dalších informací.

    snímek obrazovky WinDbg zobrazující okno zásobníků volání

  2. Pomocí příkazu kn zobrazte volací zásobník při ladění vzorového kódu adaptéru v přerušeném stavu.

    3: kd> kn
    # Child-SP          RetAddr           Call Site
    00 ffffd001`51978110 fffff801`0942f55b ECHO!EchoEvtDeviceAdd+0x66 [c:\Samples\kmdf echo sample\c++\driver\autosync\driver.c @ 138]
    01 (Inline Function) --------`-------- Wdf01000!FxDriverDeviceAdd::Invoke+0x30 [d:\wbrtm\minkernel\wdf\framework\shared\inc\private\common\fxdrivercallbacks.hpp @ 61]
    02 ffffd001`51978150 fffff801`eed8097d Wdf01000!FxDriver::AddDevice+0xab [d:\wbrtm\minkernel\wdf\framework\shared\core\km\fxdriverkm.cpp @ 72]
    03 ffffd001`51978570 fffff801`ef129423 nt!PpvUtilCallAddDevice+0x35 [d:\9142\minkernel\ntos\io\pnpmgr\verifier.c @ 104]
    04 ffffd001`519785b0 fffff801`ef0c4112 nt!PnpCallAddDevice+0x63 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 7397]
    05 ffffd001`51978630 fffff801`ef0c344f nt!PipCallDriverAddDevice+0x6e2 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 3390]
    ...
    

Zásobník volání ukazuje, že jádro (nt) volalo do kódu Plug and Play (PnP), který volal kód rozhraní ovladače (WDF), který později volal funkci ovladače echo DeviceAdd.

Zobrazení procesů a vláken

V této části zobrazte informace o procesech a vláknech spuštěných v režimu jádra.

Procesy

Informace o procesu můžete zobrazit nebo nastavit pomocí rozšíření ladicího programu !process. Nastavte bod přerušení, abyste zkoumali proces, který se používá při přehrávání zvuku.

  1. V hostitelském systému zadejte příkaz dv a prozkoumejte proměnné národního prostředí přidružené k rutině EchoEvtIo:

    0: kd> dv ECHO!EchoEvtIo*
    ECHO!EchoEvtIoQueueContextDestroy
    ECHO!EchoEvtIoWrite
    ECHO!EchoEvtIoRead         
    
  2. Pomocí bc *vymažte předchozí zarážky:

    0: kd> bc *  
    
  3. Pomocí následujícího příkazu nastavte zarážku symbolu na rutinách EchoEvtIo:

    0: kd> bm ECHO!EchoEvtIo*
      2: aade5490          @!”ECHO!EchoEvtIoQueueContextDestroy”
      3: aade55d0          @!”ECHO!EchoEvtIoWrite”
      4: aade54c0          @!”ECHO!EchoEvtIoRead”
    
  4. Vyjmenujte zarážky, abyste ověřili, že zarážky jsou správně nastavené:

    0: kd> bl
    1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197]    0001 (0001) ECHO!EchoEvtIoQueueContextDestroy
    ...
    
  5. Zadejte g pro restartování provádění kódu:

    0: kd> g
    
  6. V cílovém systému spusťte testovací program ovladače EchoApp.exe v cílovém systému.

  7. Když se v hostitelském systému spustí testovací aplikace, volá se rutina vstupně-výstupních operací v ovladači. Toto volání způsobí aktivaci zarážky a zastavení spuštění kódu ovladače v cílovém systému.

    Breakpoint 2 hit
    ECHO!EchoEvtIoWrite:
    fffff801`0bf95810 4c89442418      mov     qword ptr [rsp+18h],r8
    
  8. Pomocí příkazu !process zobrazte aktuální proces, který je součástí spuštění echoapp.exe:

    0: kd> !process
    PROCESS ffffe0007e6a7780
        SessionId: 1  Cid: 03c4    Peb: 7ff7cfec4000  ParentCid: 0f34
        DirBase: 1efd1b000  ObjectTable: ffffc001d77978c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000802c79f0 Vads 30 Clone 0 Private 135. Modified 5. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf270050
        ElapsedTime                       00:00:00.052
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (682, 50, 345) (2728KB, 200KB, 1380KB)
        PeakWorkingSetSize                652
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    688
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe00080e32080  Cid 03c4.0ec0  Teb: 00007ff7cfece000 Win32Thread: 0000000000000000 RUNNING on processor 1
    

    Výstup ukazuje, že proces je přidružený k vláknu echoapp.exe, které bylo spuštěno při dosažení zarážky v události zápisu ovladače. Další informace naleznete v tématu !process.

  9. Pomocí !process 0 0 zobrazte souhrnné informace pro všechny procesy. Ve výstupu pomocí kombinace kláves Ctrl+F vyhledejte stejnou adresu procesu, která je přidružená k echoapp.exe obrázku. V příkladu je adresa procesu ffffe0007e6a7780.

    ...
    
    PROCESS ffffe0007e6a7780
        SessionId: 1  Cid: 0f68    Peb: 7ff7cfe7a000  ParentCid: 0f34
        DirBase: 1f7fb9000  ObjectTable: ffffc001cec82780  HandleCount:  34.
        Image: echoapp.exe
    
    ...
    
  10. Poznamenejte si ID procesu přidružené k echoapp.exe pro pozdější použití v tomto cvičení. Adresu můžete také zkopírovat do vyrovnávací paměti pro pozdější použití pomocí kombinace kláves Ctrl+C.

    _____________________________________________________( procesní adresaechoapp.exe)

  11. Chcete-li pokračovat ve spuštění kódu, zadejte do ladicího programu g podle potřeby, dokud echoapp.exe nedokončí své běžení. Několikrát se zobrazí zarážka v události čtení a zápisu. Jakmile echoapp.exe skončí, vstupte do ladicího programu stisknutím klávesové kombinace Ctrl+ScrLk (Ctrl+Break).

  12. Pomocí příkazu !process potvrďte, že používáte jiný proces. Ve výstupu zobrazeném zde se proces s hodnotou Obrázek System liší od hodnoty Obrázek Echo.

    1: kd> !process
    PROCESS ffffe0007b65d900
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 001ab000  ObjectTable: ffffc001c9a03000  HandleCount: 786.
        Image: System
        VadRoot ffffe0007ce45930 Vads 14 Clone 0 Private 22. Modified 131605. Locked 64.
        DeviceMap ffffc001c9a0c220
        Token                             ffffc001c9a05530
        ElapsedTime                       21:31:02.516
    ...
    

    Výstup ukazuje, že při zastavení operačního systému byl spuštěn proces ffffe0007b65d900.

  13. Pomocí příkazu !process se pokuste podívat se na ID procesu přidruženého k echoapp.exe, které jste si poznamenali dříve. Zadejte adresu procesu echoapp.exe, kterou jste si poznamenali dříve, místo ukázkové adresy procesu uvedené v tomto příkladu.

    0: kd> !process ffffe0007e6a7780
    TYPE mismatch for process object at 82a9acc0
    

    Objekt procesu již není k dispozici, protože proces echoapp.exe již není spuštěný.

Vlákna

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

  1. V hostitelském systému zadejte do ladicího programu g, aby se znovu spustilo vykonávání kódu v cílovém systému.

  2. V cílovém systému spusťte testovací program ovladače EchoApp.exe.

  3. V hostitelském systému dojde k zarážce a spuštění kódu se zastaví.

    Breakpoint 4 hit
    ECHO!EchoEvtIoRead:
    aade54c0 55              push    ebp
    
  4. Chcete-li zobrazit spuštěná vlákna, zadejte !thread. Měly by se zobrazit informace podobné následujícímu příkladu:

    0: kd>  !thread
    THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    IRP List:
        ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0008096c900       Image:         echoapp.exe
    ...
    

    Poznamenejte si název obrázku echoapp.exe. To znamená, že se díváte na vlákno přidružené k testovací aplikaci.

  5. Pomocí příkazu !process určete, zda je toto vlákno jediným vláknem spuštěným v procesu přidruženém k echoapp.exe. Číslo běžícího vlákna v procesu je stejné jako vlákno, které zobrazil příkaz !thread.

    0: kd> !process
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf5dc050
        ElapsedTime                       00:00:00.048
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (681, 50, 345) (2724KB, 200KB, 1380KB)
        PeakWorkingSetSize                651
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    686
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    
  6. Pomocí příkazu !process 0 0 vyhledejte adresu procesu dvou souvisejících procesů a sem zaznamenejte adresu tohoto procesu.

    Cmd.exe: ____________________________________________________________

    EchoApp.exe: _______________________________________________________

    0: kd> !process 0 0 
    
    …
    
    PROCESS ffffe0007bbde900
        SessionId: 1  Cid: 0f34    Peb: 7ff72dfa7000  ParentCid: 0c64
        DirBase: 19c5fa000  ObjectTable: ffffc001d8c2f300  HandleCount:  31.
        Image: cmd.exe
    …
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
    …
    

    Případně můžete použít !process 0 17 k zobrazení podrobných informací o každém procesu. Výstup tohoto příkazu může být dlouhý. Výstup je možné prohledávat pomocí Ctrl+F.

  7. Pomocí příkazu !process zobrazte seznam informací o procesu pro oba procesy, na kterých běží váš počítač. Zadejte adresu procesu z výstupu !process 0 0, nikoli adresu zobrazenou v tomto příkladu.

    Tento příklad výstupu je pro ID procesu cmd.exe, které bylo zaznamenáno dříve. Název image pro toto ID procesu je cmd.exe.

    0: kd>  !process ffffe0007bbde900
    PROCESS ffffe0007bbde900
        SessionId: 1  Cid: 0f34    Peb: 7ff72dfa7000  ParentCid: 0c64
        DirBase: 19c5fa000  ObjectTable: ffffc001d8c2f300  HandleCount:  31.
        Image: cmd.exe
        VadRoot ffffe0007bb8e7b0 Vads 25 Clone 0 Private 117. Modified 20. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001d8c48050
        ElapsedTime                       21:33:05.840
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         24656
        QuotaPoolUsage[NonPagedPool]      3184
        Working Set Sizes (now,min,max)  (261, 50, 345) (1044KB, 200KB, 1380KB)
        PeakWorkingSetSize                616
        VirtualSize                       2097164 Mb
        PeakVirtualSize                   2097165 Mb
        PageFaultCount                    823
        MemoryPriority                    FOREGROUND
        BasePriority                      8
        CommitCharge                      381
    
            THREAD ffffe0007cf34880  Cid 0f34.0f1c  Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
                ffffe0008096c900  ProcessObject
            Not impersonating
    ...
    

    Tento příklad výstupu je pro ID procesu echoapp.exe, které bylo zaznamenáno dříve.

    0: kd>  !process ffffe0008096c900
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf5dc050
        ElapsedTime                       00:00:00.048
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (681, 50, 345) (2724KB, 200KB, 1380KB)
        PeakWorkingSetSize                651
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    686
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
            IRP List:
                ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
            Not impersonating
    ...
    
  8. Poznamenejte si první adresu vlákna přidruženou k dvěma procesům.

    Cmd.exe: ____________________________________________________

    EchoApp.exe: _________________________________________________

  9. Pomocí příkazu !Thread zobrazte informace o aktuálním vlákně.

    0: kd>  !Thread
    THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    IRP List:
        ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0008096c900       Image:         echoapp.exe
    Attached Process          N/A            Image:         N/A
    ...
    

    Podle očekávání je aktuální vlákno přidružené k echoapp.exe a je ve spuštěném stavu.

  10. Pomocí příkazu !Thread zobrazte informace o vlákně přidruženém k procesu cmd.exe. Zadejte adresu vlákna, kterou jste si poznamenali dříve.

    0: kd> !Thread ffffe0007cf34880
    THREAD ffffe0007cf34880  Cid 0f34.0f1c  Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
        ffffe0008096c900  ProcessObject
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0007bbde900       Image:         cmd.exe
    Attached Process          N/A            Image:         N/A
    Wait Start TickCount      4134621        Ticks: 0
    Context Switch Count      4056           IdealProcessor: 0             
    UserTime                  00:00:00.000
    KernelTime                00:00:01.421
    Win32 Start Address 0x00007ff72e9d6e20
    Stack Init ffffd0015551dc90 Current ffffd0015551d760
    Base ffffd0015551e000 Limit ffffd00155518000 Call 0
    Priority 14 BasePriority 8 UnusualBoost 3 ForegroundBoost 2 IoPriority 2 PagePriority 5
    Child-SP          RetAddr           : Args to Child                                                           : Call Site
    ffffd001`5551d7a0 fffff801`eed184fe : fffff801`eef81180 ffffe000`7cf34880 00000000`fffffffe 00000000`fffffffe : nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109]
    ffffd001`5551d8e0 fffff801`eed17f79 : ffff03a5`ca56a3c8 000000de`b6a6e990 000000de`b6a6e990 00007ff7`d00df000 : nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347]
    ffffd001`5551d980 fffff801`eecea340 : ffffd001`5551da18 00000000`00000000 00000000`00000000 00000000`00000388 : nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619]
    ...
    

    Toto vlákno je přidružené k cmd.exe a je ve stavu čekání.

  11. Zadejte adresu vlákna čekající CMD.exe podprocesu a změňte kontext na toto čekající vlákno.

    0: kd> .Thread ffffe0007cf34880
    Implicit thread is now ffffe000`7cf34880
    
  12. Pomocí příkazu k zobrazte zásobník volání přidružený k čekajícímu podprocesu.

    0: kd> k
      *** Stack trace for last set context - .thread/.cxr resets it
    # Child-SP          RetAddr           Call Site
    00 ffffd001`5551d7a0 fffff801`eed184fe nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109]
    01 ffffd001`5551d8e0 fffff801`eed17f79 nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347]
    02 ffffd001`5551d980 fffff801`eecea340 nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619]
    03 ffffd001`5551da00 fffff801`ef02e642 nt!KeWaitForSingleObject+0x2c0 [d:\9142\minkernel\ntos\ke\wait.c @ 683]
    ...
    

    Prvky zásobníku volání, takové jako KiCommitThreadWait, značí, že toto vlákno neprobíhá podle očekávání.

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

IRQL, zaregistruje a ukončí relaci WinDbg.

V této části zobrazte úroveň žádosti o přerušení (IRQL) a obsah registrů.

Zobrazit uložený IRQL

IrQL slouží 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 neruší aktuální operaci. Přerušení, ke kterému dochází nad nastavením IRQL procesoru, má přednost před aktuální operací.

V hostitelském systému rozšíření !irql zobrazuje IRQL na současné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řerušením ladicího programu, se uloží a je zobrazen pomocí !irql.

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

Zobrazení registrů

V hostitelském systému zobrazte obsah registrů pro aktuální vlákno v aktuálním procesoru pomocí příkazu r (Registers).

0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
 r8=000000000000003e  r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc              int     3

Obsah registrů můžete zobrazit také tak, že vyberete Zobrazení>Registrů. Více informací naleznete v sekci r (Registry).

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 o zpětném překladu jazyka sestavení naleznete v tématu Annotated x86 Disassembly a Annotated x64 disassembly.

Pro informace o obsahu registru viz architektury x86 a architektury x64.

Ukončení relace WinDbg

Pokud chcete nechat ladicí program připojený, ale chcete pracovat na cíli, vymažte všechny zarážky pomocí bc *, aby se cílový počítač nepokusil 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 části Ukončení ladicí relace ve WinDbg.

Prostředky ladění Windows

Další informace jsou k dispozici v ladění Systému Windows. Některé z těchto knih používají starší verze Windows, jako například Windows Vista, ale koncepty, o kterých diskutují, platí pro většinu verzí Windows.

Viz také