Sdílet prostřednictvím


Začínáme s WinDbg (režim jádra)

Ladicí program systému Windows (WinDbg) je ladicí program v režimu jádra a ladicího programu v uživatelském režimu, který je součástí nástrojů pro ladění systému Windows. Tento článek obsahuje cvičení, která vám pomůžou začít používat WinDbg jako ladicí program v režimu jádra.

Pokud chcete získat WinDbg, přečtěte si téma Stažení a instalace ladicího programu systému Windows (WinDbg).

Nastavení ladění v režimu jádra

A kernel-mode debugging environment typically has two computers, the host computer and the target computer. Ladicí program běží na hostitelském počítači a laděný kód běží na cílovém počítači. Počítač a cílové zařízení jsou připojeny ladicím kabelem.

Ladicí programy systému Windows podporují následující typy kabelů:

  • Ethernet
  • USB 3.0
  • Serial (also called null modem)

Pro rychlost a spolehlivost byste měli použít ethernetový kabel s místním síťovým rozbočovačem. Následující diagram znázorňuje hostitelský a cílový počítač připojený k ladění pomocí ethernetového kabelu:

Diagram znázorňující hostitelské a cílové počítače připojené pomocí ethernetového kabelu pro ladění

Možnost pro starší verze Systému Windows je použití přímého kabelu, například sériového kabelu:

Diagram znázorňující hostitelské a cílové počítače připojené pomocí ladicího kabelu pro ladění

Spusťte proces podle postupu nastavení požadované konfigurace:

Založte ladicí relaci v režimu jádra

Po nastavení hostitelského a cílového počítače a jejich připojení pomocí ladicího kabelu můžete zahájit ladicí relaci režimu jádra.

Pokračujte pokyny v článku, který jste použili pro proces nastavení. Pokud například nastavíte hostitele a cílové počítače pro ladění přes ethernetový kabel pro ladění v režimu jádra, postupujte podle pokynů v části Nastavení ladění jádra KDNET automaticky.

Spuštění ladění pomocí WinDbg

Pokud chcete začít používat WinDbg pro ladicí relaci, postupujte takto:

  1. Na hostitelském počítači otevřete WinDbg a nastavte ladicí relaci režimu jádra s cílovým počítačem.

  2. Open the debugger documentation CHM (.chm) file by selecting Help>Contents.

    Dokumentace k ladicím programu je také k dispozici online v nástrojích ladění pro Windows. Další informace naleznete v tématu Instalace ladicího programu systému Windows.

  3. Když navážete ladicí relaci v režimu jádra, může WinDbg automaticky přerušit cílový počítač. If WinDbg doesn't break in, select Debug>Break.

  4. V příkazovém řádku v dolní části okna WinDbg spusťte následující příkazy:

    1. Nastavte cestu symbolu pomocí příkazu .sympath (Symbol Path).

      .sympath srv*
      

      Výstup je podobný tomuto příkladu:

      Symbol search path is: srv*
      Expanded Symbol search path is: cache*;SRV*https://msdl.microsoft.com/download/symbols
      

      The symbol search path tells WinDbg where to look for symbol program database (PDB) files (.pdb). Ladicí program potřebuje soubory symbolů k získání informací o modulech kódu, jako jsou názvy funkcí a názvy proměnných.

    2. Run the .reload command so WinDbg starts finding and loading symbols files.

      .reload
      
  5. View a list of loaded modules with the lm command.

    lm
    

    Výstup je podobný tomuto příkladu:

    0:000>3: kd> lm
    start               end                 module name
    fffff800`00000000   fffff800`00088000   CI            (deferred)
    ...
    fffff800`01143000   fffff800`01151000   BasicRender   (deferred)
    fffff800`01151000   fffff800`01163000   BasicDisplay  (deferred)
    ...
    fffff800`02a0e000   fffff800`03191000   nt  (pdb symbols) C:\...\ntkrnlmp.pdb
    fffff800`03191000   fffff800`03200000   hal (deferred)
    ...
    
  6. Start the target computer running again with the g (Go) command.

    g
    
  7. Break in to the target computer again by selecting Debug>Break.

  8. Spusťte příkaz dt (Typ zobrazení) a prozkoumejte _FILE_OBJECT datový typ v nt modulu:

    dt nt!_FILE_OBJECT
    

    Výstup je podobný tomuto příkladu:

    0:000>0: kd> dt nt!_FILE_OBJECT
       +0x000 Type                 : Int2B
       +0x002 Size                 : Int2B
       +0x008 DeviceObject         : Ptr64 _DEVICE_OBJECT
       +0x010 Vpb                  : Ptr64 _VPB
       ...
       +0x0c0 IrpList              : _LIST_ENTRY
       +0x0d0 FileObjectExtension  : Ptr64 Void
    
  9. Spusťte příkaz x (Prozkoumat symboly) a prohlédněte si některé symboly v nt modulu:

    x nt!\*CreateProcess\*
    

    Výstup je podobný tomuto příkladu:

    0:000>0: kd> x nt!*CreateProcess*
    fffff800`030821cc   nt!ViCreateProcessCallbackInternal (<no parameter info>)
    ...
    fffff800`02e03904   nt!MmCreateProcessAddressSpace (<no parameter info>)
    fffff800`02cece00   nt!PspCreateProcessNotifyRoutine = <no type information>
    ...
    
  10. Spuštěním příkazů bu (Set Breakpoint) a bl (Seznam zarážek) nastavte a zkontrolujte zarážky:

    bu Použijte příkaz a nastavte zarážku při volání Systému Windows do rutinyMmCreateProcessAddressSpace. Potom spusťte bl příkaz a ověřte, že je zarážka nastavená.

    bu nt!MmCreateProcessAddressSpace
    bl
    

    Výstup je podobný tomuto příkladu:

    0:000>0: kd> bu nt!MmCreateProcessAddressSpace
    0: kd> bl
    0 e fffff800`02e03904  0001 (0001) nt!MmCreateProcessAddressSpace
    
  11. Zadáním g klávesy (Go) nechte cílový počítač běžet.

    g
    

    Cílový počítač se při volání rutiny MmCreateProcessAddressSpace rozdělí do ladicího programu.

    Pokud se cílový počítač okamžitě nerozčlení do ladicího programu, proveďte na cílovém počítači několik akcí. Otevřete třeba Poznámkový blok a uložte soubor.

  12. Zobrazte trasování zásobníku .reload pomocí příkazů and k (Display Stack Backtrace):

    .reload
    k
    

    Výstup je podobný tomuto příkladu:

    0:000>2: kd> k
    Child-SP            RetAddr             Call Site
    ffffd000`224b4c88   fffff800`02d96834   nt!MmCreateProcessAddressSpace
    ffffd000`224b4c90   fffff800`02dfef17   nt!PspAllocateProcess+0x5d4
    ffffd000`224b5060   fffff800`02b698b3   nt!NtCreateUserProcess+0x55b
    ...
    000000d7`4167fbb0   00007ffd`14b064ad   KERNEL32!BaseThreadInitThunk+0xd
    000000d7`4167fbe0   00000000`00000000   ntdll!RtlUserThreadStart+0x1d
    
  13. Select View>Disassembly. Then select Debug>Step Over (or select F10).

    Enter step commands a few more times as you watch the output in the Disassembly window.

  14. Pomocí příkazu bc (Breakpoint Clear) vymažte zarážku .

    bc *
    
  15. Zadáním g klávesy (Go) nechte cílový počítač běžet.

    g
    

    To break in again, select Debug>Break, or select CTRL-Break.

  16. View a list of all processes with the !process command:

    !process 0 0
    

    Výstup je podobný tomuto příkladu:

    0:000>0: kd> !process 0 0
    **** NT ACTIVE PROCESS DUMP ****
    PROCESS ffffe000002287c0
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 001aa000  ObjectTable: ffffc00000003000  HandleCount: <Data Not Accessible>
        Image: System
    
    PROCESS ffffe00001e5a900
        SessionId: none  Cid: 0124    Peb: 7ff7809df000  ParentCid: 0004
        DirBase: 100595000  ObjectTable: ffffc000002c5680  HandleCount: <Data Not Accessible>
        Image: smss.exe
    ...
    PROCESS ffffe00000d52900
        SessionId: 1  Cid: 0910    Peb: 7ff669b8e000  ParentCid: 0a98
        DirBase: 3fdba000  ObjectTable: ffffc00007bfd540  HandleCount: <Data Not Accessible>
        Image: explorer.exe
    
  17. Zkopírujte adresu procesu, například ffffe00000d52900, a zobrazte informace o procesu pomocí !process příkazu. <process-address> Nahraďte část adresou procesu:

    !process <process-address> 2
    

    Výstup procesu ffffe00000d52900 ukazuje následující vlákna v procesu:

    0:000>0:000>0: kd> !process ffffe00000d52900 2
    PROCESS ffffe00000d52900
        SessionId: 1  Cid: 0910    Peb: 7ff669b8e000  ParentCid: 0a98
        DirBase: 3fdba000  ObjectTable: ffffc00007bfd540  HandleCount:
         Image: explorer.exe
    
            THREAD ffffe00000a0d880  Cid 0910.090c  Teb: 00007ff669b8c000
                ffffe00000d57700  SynchronizationEvent
    
            THREAD ffffe00000e48880  Cid 0910.0ad8  Teb: 00007ff669b8a000
                ffffe00000d8e230  NotificationEvent
                ffffe00000cf6870  Semaphore Limit 0xffff
                ffffe000039c48c0  SynchronizationEvent
            ...
            THREAD ffffe00000e6d080  Cid 0910.0cc0  Teb: 00007ff669a10000
                ffffe0000089a300  QueueObject
    
  18. Copy the address for a thread, such as ffffe00000e6d080, and view the thread information with the !thread command. <thread-address> Nahraďte část adresou vlákna:

    !thread <thread-ddress>
    

    Výstup pro ffffe00000e6d080 vlákno zobrazuje následující souhrnné informace:

    0: kd> !thread ffffe00000e6d080
    THREAD ffffe00000e6d080  Cid 0910.0cc0  Teb: 00007ff669a10000 Win32Thread: 0000000000000000 WAIT: ...
        ffffe0000089a300  QueueObject
    Not impersonating
    DeviceMap                 ffffc000034e7840
    Owning Process            ffffe00000d52900       Image:         explorer.exe
    Attached Process          N/A            Image:         N/A
    Wait Start TickCount      13777          Ticks: 2 (0:00:00:00.031)
    Context Switch Count      2              IdealProcessor: 1
    UserTime                  00:00:00.000
    KernelTime                00:00:00.000
    Win32 Start Address ntdll!TppWorkerThread (0x00007ffd14ab2850)
    Stack Init ffffd00021bf1dd0 Current ffffd00021bf1580
    Base ffffd00021bf2000 Limit ffffd00021bec000 Call 0
    Priority 13 BasePriority 13 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
    ...
    
  19. View all the device nodes in the Plug and Play device tree with the !devnode command:

    !devnode 0 1
    

    Výstup je podobný tomuto příkladu:

    0:000>0: kd> !devnode 0 1
    Dumping IopRootDeviceNode (= 0xffffe000002dbd30)
    DevNode 0xffffe000002dbd30 for PDO 0xffffe000002dc9e0
      InstancePath is "HTREE\ROOT\0"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
      DevNode 0xffffe000002d9d30 for PDO 0xffffe000002daa40
        InstancePath is "ROOT\volmgr\0000"
        ServiceName is "volmgr"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeEnumerateCompletion (0x30d)
        DevNode 0xffffe00001d49290 for PDO 0xffffe000002a9a90
          InstancePath is "STORAGE\Volume\{3007dfd3-df8d-11e3-824c-806e6f6e6963}#0000000000100000"
          ServiceName is "volsnap"
          TargetDeviceNotify List - f 0xffffc0000031b520  b 0xffffc0000008d0f0
          State = DeviceNodeStarted (0x308)
          Previous State = DeviceNodeStartPostWork (0x307)
    ...
    
  20. Pomocí příkazu zobrazte uzly zařízení a jejich hardwarové prostředky !devnode :

    !devnode 0 9
    

    Výstup je podobný tomuto příkladu:

    0:000>...
            DevNode 0xffffe000010fa770 for PDO 0xffffe000010c2060
              InstancePath is "PCI\VEN_8086&DEV_2937&SUBSYS_2819103C&REV_02\3&33fd14ca&0&D0"
              ServiceName is "usbuhci"
              State = DeviceNodeStarted (0x308)
              Previous State = DeviceNodeEnumerateCompletion (0x30d)
              TranslatedResourceList at 0xffffc00003c78b00  Version 1.1  Interface 0x5  Bus #0
                Entry 0 - Port (0x1) Device Exclusive (0x1)
                  Flags (0x131) - PORT_MEMORY PORT_IO 16_BIT_DECODE POSITIVE_DECODE
                  Range starts at 0x3120 for 0x20 bytes
                Entry 1 - DevicePrivate (0x81) Device Exclusive (0x1)
                  Flags (0000) -
                  Data - {0x00000001, 0x00000004, 0000000000}
                Entry 2 - Interrupt (0x2) Shared (0x3)
                  Flags (0000) - LEVEL_SENSITIVE
                  Level 0x8, Vector 0x81, Group 0, Affinity 0xf
    ...
    
  21. Pomocí příkazu zobrazte uzel zařízení, který má název služby disk !devnode :

    !devnode 0 1 disk
    

    Výstup je podobný tomuto příkladu:

    0: kd> !devnode 0 1 disk
    Dumping IopRootDeviceNode (= 0xffffe000002dbd30)
    DevNode 0xffffe0000114fd30 for PDO 0xffffe00001159610
      InstancePath is "IDE\DiskST3250820AS_____________________________3.CHL___\5&14544e82&0&0.0.0"
      ServiceName is "disk"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
    ...
    
  22. Výstup !devnode 0 1 příkazu zobrazuje adresu objektu fyzického zařízení (PDO) uzlu.

    Copy the address of a PDO, such as 0xffffe00001159610, and view the PDO details with the !devstack command. <PDO-address> Část nahraďte informacemi o pdo:

    !devstack <PDO-address>
    

    Výstup vlákna pdo 0xffffe00001159610 ukazuje následující zásobník zařízení:

    0:000>0: kd> !devstack 0xffffe00001159610
      !DevObj           !DrvObj            !DevExt           ObjectName
      ffffe00001d50040  \Driver\partmgr    ffffe00001d50190  
      ffffe00001d51450  \Driver\disk       ffffe00001d515a0  DR0
      ffffe00001156e50  \Driver\ACPI       ffffe000010d8bf0  
    
  23. Get information about the disk.sys driver object with the !drvobj command and the driver name "disk":

    !drvobj disk 2
    

    Výstup zobrazuje podrobné informace o objektu ovladače:

    0:000>0: kd> !drvobj disk 2
    Driver object (ffffe00001d52680) is for:
     \Driver\disk
    DriverEntry:   fffff800006b1270 disk!GsDriverEntry
    DriverStartIo: 00000000
    DriverUnload:  fffff800010b0b5c CLASSPNP!ClassUnload
    AddDevice:     fffff800010aa110 CLASSPNP!ClassAddDevice
    
    Dispatch routines:
    [00] IRP_MJ_CREATE                      fffff8000106d160    CLASSPNP!ClassGlobalDispatch
    [01] IRP_MJ_CREATE_NAMED_PIPE           fffff80002b0ab24    nt!IopInvalidDeviceRequest
    [02] IRP_MJ_CLOSE                       fffff8000106d160    CLASSPNP!ClassGlobalDispatch
    [03] IRP_MJ_READ                        fffff8000106d160    CLASSPNP!ClassGlobalDispatch
    ...
    [1b] IRP_MJ_PNP                         fffff8000106d160    CLASSPNP!ClassGlobalDispatch
    
  24. Výstup !drvobj příkazu zobrazuje adresy rutin odeslání, například CLASSPNP!ClassGlobalDispatch. Nastavte a ověřte zarážku v rutině ClassGlobalDispatch pomocí následujících příkazů:

    bu CLASSPNP!ClassGlobalDispatch
    bl
    
  25. Zadáním g klávesy (Go) nechte cílový počítač běžet.

    g
    

    Cílový počítač se při volání rutiny ClassGlobalDispatch rozdělí do ladicího programu.

    Pokud se cílový počítač okamžitě nezačlení do ladicího programu, proveďte na cílovém počítači několik akcí. Nebo například otevřete Poznámkový blok a uložte soubor.

  26. Zobrazte trasování zásobníku pomocí následujících příkazů:

    .reload
    k
    

    Výstup je podobný tomuto příkladu:

    2: kd> k
    Child-SP          RetAddr           Call Site
    ffffd000`21d06cf8 fffff800`0056c14e CLASSPNP!ClassGlobalDispatch
    ffffd000`21d06d00 fffff800`00f2c31d volmgr!VmReadWrite+0x13e
    ffffd000`21d06d40 fffff800`0064515d fvevol!FveFilterRundownReadWrite+0x28d
    ffffd000`21d06e20 fffff800`0064578b rdyboost!SmdProcessReadWrite+0x14d
    ffffd000`21d06ef0 fffff800`00fb06ad rdyboost!SmdDispatchReadWrite+0x8b
    ffffd000`21d06f20 fffff800`0085cef5 volsnap!VolSnapReadFilter+0x5d
    ffffd000`21d06f50 fffff800`02b619f7 Ntfs!NtfsStorageDriverCallout+0x16
    ...
    
  27. Pomocí příkazu qd (Quit and Detach) ukončete ladicí relaci.

    qd
    

Souhrn příkazů

Následující odkazy obsahují další informace o příkazech popsaných v tomto článku.

For more information about menu commands like Debug>Break and Help>Contents, see the Get started with WinDbg (user-mode) article.