Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V této příručce se dozvíte, jak pomocí WinDbg ladit aplikace v uživatelském režimu. Základní dovednosti ladění si procvičíte tak, že se připojíte ke spuštěnému procesu, nastavíte body přerušení a diagnostikujete chybové ukončení aplikace.
V tomto článku:
- Připojení WinDbg k Poznámkovém bloku a prozkoumání základního ladění
- Ladění vlastní aplikace a analýza chybového ukončení
- Osvojte si základní příkazy ladění
Co se naučíte
- Připojení WinDbg ke spuštěném procesu
- Konfigurace souborů symbolů pro čitelný výstup ladění
- Nastavení bodů přerušení a řízení spuštění programu
- Analýza chybových ukončení aplikace
- Navigace ve vláknech a zásobnících volání
Požadavky
- WinDbg nainstalovaný na vašem počítači. Pokyny k instalaci naleznete v tématu Stažení a instalace ladicího programu systému Windows WinDbg.
- Základní znalost rozhraní příkazového řádku
- (Volitelné) Aplikace kompilovaná se symboly ladění pro druhé cvičení
Odhadovaný čas dokončení: 30 minut
Otevřete Poznámkový blok a připojte WinDbg.
Přejděte do instalačního adresáře a otevřete WinDbg.exe.
V nabídce Soubor vyberte Spustit spustitelný soubor. V dialogovém okně Spustit spustitelný soubor přejděte do složky, která obsahuje notepad.exe. (Soubor notepad.exe je obvykle v
C:\Windows\System32.) Jako název souboru zadejte notepad.exe. Vyberte Otevřít.
Nakonfigurujte soubory symbolů, aby WinDbg mohl zobrazit čitelné názvy funkcí a proměnných.
Do příkazového řádku v dolní části okna WinDbg zadejte tento příkaz:
Výstup se podobá následujícímu příkladu:
Symbol search path is: srv* Expanded Symbol search path is: cache*;SRVCo jsou symboly? Soubory symbolů (PDB) obsahují informace o modulech kódu, jako jsou názvy funkcí a názvy proměnných. Bez symbolů uvidíte jenom adresy paměti.
Pak zadejte tento příkaz:
Příkaz
.reloadříká WinDbg, aby při počátečním hledání vyhledaly a načetly soubory symbolů.Pokud chcete zobrazit symboly modulu notepad.exe , zadejte tento příkaz:
Poznámka
Pokud se nezobrazí žádný výstup, zadejte
.reload /fa pokuste se vynutit načtení symbolu. Pro zobrazení dodatečných informací o načítání symbolů použijte !sym noisy.Pokud chcete zobrazit symboly v modulu notepad.exe , který obsahuje
main, pomocí příkazu prozkoumat symboly zobrazte seznam modulů, které odpovídají masce:x notepad!wWin*Výstup se podobá následujícímu příkladu:
00007ff6`6e76b0a0 notepad!wWinMain (wWinMain) 00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)Pokud chcete nastavit zarážku na
notepad!wWinMain, zadejte tento příkaz:Pokud chcete ověřit, že jste nastavili bod přerušení, zadejte tento příkaz:
Výstup se podobá následujícímu příkladu:
0 e Disable Clear 00007ff6`6e76b0a0 0001 (0001) 0:**** notepad!wWinMainPokud chcete spustit proces Poznámkového bloku, zadejte tento příkaz:
Poznámkový blok běží, dokud se nedostane k funkci
WinMain, a pak vstoupí do ladicího nástroje.Breakpoint 0 hit notepad!wWinMain: 00007ff6`6e76b0a0 488bc4 mov rax,rspPokud chcete zobrazit seznam modulů kódu, které jsou aktuálně načteny v procesu Poznámkového bloku, zadejte tento příkaz:
Výstup se podobá následujícímu příkladu:
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)Chcete-li zobrazit trasování zásobníku, zadejte příkaz:
Výstup se podobá následujícímu příkladu:
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+0x21Pokud chcete Poznámkový blok spustit znovu, zadejte tento příkaz:
Další: Přerušíte provádění a prozkoumáte načtené moduly.
Pokud chcete přejít do Poznámkového bloku, vyberte v nabídce SouborBreak.
Pokud chcete nastavit a ověřit bod přerušení na
ZwWriteFile, zadejte tyto příkazy:Pokud chcete Poznámkový blok spustit znovu, zadejte g. V okně Poznámkového bloku zadejte nějaký text. V nabídce Soubor vyberte Uložit. Spuštěný kód se přeruší, pokud jde o
ZwCreateFile. Zadáním příkazu k zobrazte trasování zásobníku.
V okně WinDbg se nalevo od příkazového řádku zobrazí čísla procesoru a vlákna. V tomto příkladu je aktuální číslo procesoru 0 a aktuální číslo vlákna je 11 (
0:011>). V okně se zobrazí trasování zásobníku pro vlákno 11 spuštěné na procesoru 0.Pokud chcete zobrazit seznam všech vláken v procesu Poznámkového bloku, zadejte tento příkaz (vlnovku):
Výstup se podobá následujícímu příkladu:
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 UnfrozenV tomto příkladu má 14 vláken indexy 0 až 13.
Chcete-li zobrazit stopu zásobníku pro vlákno 0, zadejte tyto příkazy:
Výstup se podobá následujícímu příkladu:
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+0xdaPokud chcete ukončit ladění a odpojit od procesu Poznámkového bloku, zadejte tento příkaz:
Otevřete vlastní aplikaci a připojte WinDbg.
Předpokládejme například, že jste napsali a vytvořili tuto malou konzolovou aplikaci:
...
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);
}
V tomto cvičení předpokládejme, že sestavená aplikace (MyApp.exe) a soubor symbolů (MyApp.pdb) jsou v C:\MyApp\x64\Debug. Také předpokládejme, že zdrojový kód aplikace je v C:\MyApp\MyApp and that the target machine compiled MyApp.exe.
Otevřete WinDbg.
V nabídce Soubor vyberte Spustit spustitelný soubor. V dialogovém okně Spustitelný soubor přejděte na C:\MyApp\x64\Debug. Jakonázev souboru
zadejte MyApp.exe . Vyberte Otevřít.Zadejte tyto příkazy:
.sympath+ C:\MyApp\x64\Debug
Tyto příkazy říkají WinDbg, kde najít symboly a zdrojový kód pro vaši aplikaci. V takovém případě nemusíte pomocí cesty .srcpath nastavit umístění zdrojového kódu, protože symboly mají plně kvalifikované cesty ke zdrojovým souborům.
Zadejte tyto příkazy:
Aplikace se při dosažení funkce
mainpřeruší a spustí ladicí program.WinDbg zobrazí zdrojový kód a příkazové okno.
V nabídce Ladění vyberte Krok do (nebo vyberte F11). Pokračujte v chůzi, dokud nevkročíte do
MyFunction. Když vstoupíte do řádkuy = x / p2, aplikace se chybově ukončí a přejde do ladicího programu.Výstup se podobá následujícímu příkladu:
(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=00000000Zadejte tento příkaz:
WinDbg zobrazí analýzu problému (v tomto případě dělení nulou).
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; ...
Další kroky
Po ladění systémové aplikace i vlastního kódu můžete prozkoumat pokročilejší scénáře ladění:
- Začínáme s WinDbg (režim jádra) – Ladění jádra a ovladačů Systému Windows
- Operace ladicího programu – Informace o konceptech operací ladicího programu
- Techniky ladění – Prozkoumání pokročilých metod ladění
Souhrn příkazů
Tady jsou základní příkazy, které používáte v tomto kurzu:
Nastavení a symboly:
- .sympath (Set Symbol Path) – Konfigurace umístění, kde WinDbg najde soubory symbolů
- .reload (Reload Module) – Načtení souborů symbolů
Řízení provádění:
- g (Go) – Pokračovat v provádění programu
- bu (Set Breakpoint) – Pozastavení provádění u konkrétní funkce
-
Step Into(F11) – Provedení jedné instrukce a krokování do funkcí
Kontrola programu:
- x (Prozkoumání symbolů) – seznam funkcí a proměnných
- lm (výpis načtených modulů) – zobrazí všechny načtené knihovny DLL a spustitelné soubory.
- k (Zobrazení zásobníku zpětného sledování) – zobrazení zásobníku volání
- ~ (Stav vlákna) – Výpis všech vláken
- !analyze -v – Automatická analýza pádů
Reference:
-
bl (seznam zarážek) - ~s (Nastavit aktuální vlákno)
- .sympath+
- .srcpath (Nastavit zdrojovou cestu)
- qd (Ukončit a Odpojit)
Viz také
Začínáme s WinDbg (režimem jádra)