Megosztás a következőn keresztül:


A WinDbg használatának első lépései (felhasználói mód)

Ez az útmutató bemutatja, hogyan használható a WinDbg a felhasználói módú alkalmazások hibakeresésére. Az alapvető hibakeresési képességeket egy futó folyamathoz csatolva, töréspontok beállításával és az alkalmazás összeomlásainak diagnosztizálásával gyakorolhatja.

Ebben a cikkben:

  • Csatolja a WinDbg-et a Jegyzettömbhöz, és fedezze fel az alapvető hibakeresést.
  • Saját alkalmazás hibakeresése és összeomlás elemzése
  • Alapvető hibakeresési parancsok elsajátítása

Amit tanulsz

  • WinDbg csatolása futó folyamathoz
  • Szimbólumfájlok konfigurálása olvasható hibakeresési kimenethez
  • Töréspontok beállítása és a program végrehajtásának vezérlése
  • Alkalmazás összeomlásainak elemzése
  • Navigálás szálak és hívásveremek között

Előfeltételek

Becsült befejezési idő: 30 perc

A Jegyzettömb megnyitása és a WinDbg csatolása

  1. Lépjen be a telepítési könyvtárba, és nyissa meg a WinDbg.exe.

  2. A Fájl menüben válassza a Végrehajtható fájl indításalehetőséget. A Végrehajtható fájl indítása párbeszédpanelen lépjen a notepad.exetartalmazó mappára. (A notepad.exe fájl általában a(z) C:\Windows\System32 található.) A fájlnév mezőbe írja be a notepad.exe. Válassza a lehetőséget, majd nyissa meg alehetőséget.

    WinDbg képernyőképe, amelyen a Jegyzettömb meg van nyitva.

  3. Konfigurálja a szimbólumfájlokat, hogy a WinDbg megjeleníthesse az olvasható függvényeket és a változóneveket.

    A WinDbg ablak alján található parancssorba írja be a következő parancsot:

    .sympath srv*

    A kimenet a következő példához hasonló:

    Symbol search path is: srv*
    Expanded Symbol search path is: cache*;SRV
    

    Mik azok a szimbólumok? A szimbólumfájlok (PDB) a kódmodulokról, például a függvénynevekről és a változónevekről tartalmaznak információkat. Szimbólumok nélkül csak a memóriacímek láthatók.

    Ezután adja meg ezt a parancsot:

    .Újratöltés

    A .reload parancs arra utasítja a WinDbg-t, hogy végezze el a kezdeti keresést a szimbólumfájlok megkereséséhez és betöltéséhez.

  4. A notepad.exe modul szimbólumainak megtekintéséhez írja be ezt a parancsot:

    x jegyzettömb!*

    Jegyzet

    Ha nem jelenik meg kimenet, írd be .reload /f, hogy próbáld meg a szimbólumok betöltését kényszeríteni. A !sym zaj használatával további szimbólumbetöltési információkat jeleníthet meg.

    A notepad.exe modulban maintalálható szimbólumok megtekintéséhez használja a vizsgaszimbólumok parancsot a maszknak megfelelő modulok listázásához:

    x notepad!wWin*

    A kimenet a következő példához hasonló:

    00007ff6`6e76b0a0 notepad!wWinMain (wWinMain)
    00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)
    
  5. Töréspontot az notepad!wWinMain-nél úgy helyezhet el, hogy beírja a következő parancsot:

    bu jegyzettömb!wWinMain

    A töréspont beállításának ellenőrzéséhez írja be a következő parancsot:

    bl

    A kimenet a következő példához hasonló:

    0 e Disable Clear  00007ff6`6e76b0a0     0001 (0001)  0:**** notepad!wWinMain
    
  6. A Jegyzettömb folyamat elindításához írja be a következő parancsot:

    g

    A jegyzettömb addig fut, amíg a WinMain függvényhez nem ér, majd bepattan a hibakeresőbe.

    Breakpoint 0 hit
    notepad!wWinMain:
    00007ff6`6e76b0a0 488bc4          mov     rax,rsp
    

    A Jegyzettömb folyamatában jelenleg betöltött kódmodulok listájának megtekintéséhez írja be ezt a parancsot:

    Lm

    A kimenet a következő példához hasonló:

    0:000> lm
    start             end                 module name
    00007ff6`6e760000 00007ff6`6e798000   notepad    (pdb symbols)          C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb
    00007ff8`066a0000 00007ff8`067ab000   gdi32full   (deferred)             
    00007ff8`067b0000 00007ff8`068b0000   ucrtbase   (deferred)             
    00007ff8`06a10000 00007ff8`06aad000   msvcp_win   (deferred)             
    00007ff8`06ab0000 00007ff8`06ad2000   win32u     (deferred)             
    00007ff8`06b40000 00007ff8`06e08000   KERNELBASE   (deferred)             
    00007ff8`07220000 00007ff8`072dd000   KERNEL32   (deferred)             
    00007ff8`07420000 00007ff8`07775000   combase    (deferred)             
    00007ff8`07820000 00007ff8`079c0000   USER32     (deferred)             
    00007ff8`079c0000 00007ff8`079f0000   IMM32      (deferred)             
    00007ff8`07c00000 00007ff8`07c2a000   GDI32      (deferred)             
    00007ff8`08480000 00007ff8`085ab000   RPCRT4     (deferred)             
    00007ff8`085b0000 00007ff8`0864e000   msvcrt     (deferred)             
    00007ff8`08c40000 00007ff8`08cee000   shcore     (deferred)             
    00007ff8`08db0000 00007ff8`08fa5000   ntdll      (pdb symbols)          C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb
    00007fff`f8580000 00007fff`f881a000   COMCTL32   (deferred)    
    

    A veremkövetés megtekintéséhez írja be ezt a parancsot:

    k

    A kimenet a következő példához hasonló:

    0:000> k
    00 000000c8`2647f708 00007ff6`6e783d36     notepad!wWinMain
    01 000000c8`2647f710 00007ff8`07237034     notepad!__scrt_common_main_seh+0x106
    02 000000c8`2647f750 00007ff8`08e02651     KERNEL32!BaseThreadInitThunk+0x14
    03 000000c8`2647f780 00000000`00000000     ntdll!RtlUserThreadStart+0x21
    
  7. A Jegyzettömb újbóli elindításához írja be ezt a parancsot:

    g

    Következő: Megszakítja a végrehajtást, és megismeri a betöltött modulokat.

  8. A Jegyzettömbbe való betöréshez a Fájl menüben válassza a Megszakításlehetőséget.

  9. A ZwWriteFiletöréspont beállításához és ellenőrzéséhez adja meg a következő parancsokat:

    bu ntdll!ZwWriteFile

    bl

  10. A Jegyzettömb újbóli elindításához írja be a következőt: g. A Jegyzettömb ablakban írjon be egy szöveget. A Fájl menüben válassza ki a Mentéslehetőséget. Amikor a futó kód megakad vagy hiba lép fel a ZwCreateFile-nál. Adja meg a k parancsot a veremnyomkövetés megtekintéséhez.

    A WinDbg-ben látható veremkövetés képernyőképe.

    A WinDbg ablakban, a parancssortól balra a processzor és a szálszámok jelennek meg. Ebben a példában az aktuális processzorszám 0, az aktuális szálszám pedig 11 (0:011>). Az ablakban megjelenik a 0. processzoron futó 11. szál veremkövetése.

  11. A Jegyzettömb folyamat összes szálának listájának megtekintéséhez írja be ezt a parancsot (a tilde-t):

    ~

    A kimenet a következő példához hasonló:

    0:011> ~
       0  Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen
       1  Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen
        2  Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen
        3  Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen
        4  Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen
        5  Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen
        6  Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen
        7  Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen
        8  Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen
       10  Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen
     . 11  Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen
       12  Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen
       13  Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 Unfrozen
    

    Ebben a példában 14 szál indexe 0 és 13 között van.

  12. A 0. szál veremkövetésének megtekintéséhez adja meg az alábbi parancsokat:

    ~0-s

    k

    A kimenet a következő példához hasonló:

    0:011> ~0s
    0:011> ~0s
    win32u!NtUserGetProp+0x14:
    00007ff8`06ab1204 c3              ret
    0:000> k
     # Child-SP          RetAddr               Call Site
    00 000000c8`2647bd08 00007ff8`07829fe1     win32u!NtUserGetProp+0x14
    01 000000c8`2647bd10 00007fff`f86099be     USER32!GetPropW+0xd1
    02 000000c8`2647bd40 00007ff8`07d12f4d     COMCTL32!DefSubclassProc+0x4e
    03 000000c8`2647bd90 00007fff`f8609aba     SHELL32!CAutoComplete::_EditWndProc+0xb1
    04 000000c8`2647bde0 00007fff`f86098b7     COMCTL32!CallNextSubclassProc+0x9a
    05 000000c8`2647be60 00007ff8`0782e858     COMCTL32!MasterSubclassProc+0xa7
    06 000000c8`2647bf00 00007ff8`0782de1b     USER32!UserCallWinProcCheckWow+0x2f8
    07 000000c8`2647c090 00007ff8`0782d68a     USER32!SendMessageWorker+0x70b
    08 000000c8`2647c130 00007ff8`07afa4db     USER32!SendMessageW+0xda
    
  13. Ha ki szeretne lépni a hibakeresésből, és le szeretne lépni a Jegyzettömb folyamatáról, írja be a következő parancsot:

    Qd

Saját alkalmazás megnyitása és a WinDbg csatolása

Tegyük fel például, hogy ezt a kis konzolalkalmazást írta és építette:

...
void MyFunction(long p1, long p2, long p3)
{
    long x = p1 + p2 + p3;
    long y = 0;
    y = x / p2;
}

void main ()
{
    long a = 2;
    long b = 0;
    MyFunction(a, b, 5);
}

Ebben a gyakorlatban tegyük fel, hogy a beépített alkalmazás (MyApp.exe) és a szimbólumfájl (MyApp.pdb) a C:\MyApp\x64\Debug fájlban található. Azt is feltételezzük, hogy az alkalmazás forráskódja a C:\MyApp\MyApp and that the target machine compiled MyApp.exe-ban található.

  1. Nyissa meg a WinDbg-t.

  2. A Fájl menüben válassza a Végrehajtható fájl indításalehetőséget. A Végrehajtható fájl indítása párbeszédpanelen lépjen a C:\MyApp\x64\Debug elemre. A fájlnévesetén írja be a MyApp.exe. Válassza a lehetőséget, majd nyissa meg alehetőséget.

  3. Adja meg a következő parancsokat:

    .symfix

    .sympath+ C:\MyApp\x64\Debug

    Ezek a parancsok jelzik a WinDbg-nek, hogy hol találhatók az alkalmazás szimbólumai és forráskódja. Ebben az esetben nem kell beállítania a forráskód helyét a .srcpath használatával, mert a szimbólumok teljes elérési úttal rendelkeznek a forrásfájlokhoz.

  4. Adja meg a következő parancsokat:

    .Újratöltés

    bu MyApp!main

    g

    Az alkalmazás a hibakeresőbe tör be, amikor eléri a függvényt main .

    A WinDbg megjeleníti a forráskódot és a Parancs ablakot.

    WinDbg-ben megjelenített forráskód képernyőképe.

  5. A Hibakeresés menüben válassza a Belelépés (vagy az F11) lehetőséget. Lépjen tovább, amíg be nem lép a MyFunction-ba. Amikor belép az y = x / p2sorba, az alkalmazás összeomlik, és elindul a hibakereső.

    A kimenet a következő példához hasonló:

    (1450.1424): Integer divide-by-zero - code c0000094 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    MyApp!MyFunction+0x44:
    00007ff6`3be11064 f77c2428    idiv  eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000
    
  6. Adja meg ezt a parancsot:

    !analyze -v

    A WinDbg megjeleníti a probléma elemzését (ebben az esetben 0-ra osztva).

    FAULTING_IP:
    MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7]
    00007ff6`3be11064 f77c2428        idiv    eax,dword ptr [rsp+28h]
    
    EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
    ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044)
       ExceptionCode: c0000094 (Integer divide-by-zero)
      ExceptionFlags: 00000000
    NumberParameters: 0
    ...
    STACK_TEXT:  
    00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44
    00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38
    00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d
    00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe
    00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd
    00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d
    
    STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb
    
    FOLLOWUP_IP:
    MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7]
    00007ff6`3be11064 f77c2428        idiv    eax,dword ptr [rsp+28h]
    
    FAULTING_SOURCE_LINE:  c:\myapp\myapp\myapp.cpp
    
    FAULTING_SOURCE_FILE:  c:\myapp\myapp\myapp.cpp
    
    FAULTING_SOURCE_LINE_NUMBER:  7
    
    FAULTING_SOURCE_CODE:  
         3: void MyFunction(long p1, long p2, long p3)
         4: {
         5:     long x = p1 + p2 + p3;
         6:     long y = 0;
    >    7:  y = x / p2;
         8: }
         9:
        10: void main ()
        11: {
        12:     long a = 2;
    ...
    

Következő lépések

A rendszeralkalmazás és a saját kód hibakeresése után készen áll a fejlettebb hibakeresési forgatókönyvek megismerésére:

Parancsok összegzése

Az oktatóanyagban az alábbi alapvető parancsokat használja:

Beállítás és szimbólumok:

Végrehajtás szabályozása:

  • g (Go) – Program végrehajtásának folytatása
  • bu (Töréspont beállítása) – Végrehajtás szüneteltetése egy adott függvénynél
  • Step Into (F11) – Egy utasítás végrehajtása és lépés a függvényekbe

A program vizsgálata:

Hivatkozás:

Lásd még:

Első lépések a WinDbg (kernelmód)

Hibakereső művelet

hibakeresési technikák

A WinDbg Windows hibakereső letöltése és telepítése

WinDbg-szolgáltatások