Sdílet prostřednictvím


Použití rozšíření !analyze

Prvním krokem při ladění cílového počítače nebo aplikace s chybovým ukončením je použití rozšířeného příkazu !analyze. Toto rozšíření provádí velké množství automatizovaných analýz. Výsledky této analýzy se zobrazí v příkazovém okně ladicího programu.

Možnost -v byste měli použít pro úplné podrobné zobrazení dat. Podrobnosti o dalších možnostech najdete na stránce !analyze reference.

Příklad User-Mode !analyze -v

V tomto příkladu je ladicí program připojen k aplikaci v uživatelském režimu, která narazila na výjimku.

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Debugger SolutionDb Connection::Open failed 80004005

Pokud jste připojeni k internetu, odladovač se pokusí získat přístup k databázi řešení zhroucení spravované společností Microsoft. V tomto případě se zobrazila chybová zpráva, která značí, že váš počítač nemohl získat přístup k internetu nebo že web nefunguje.

FAULTING_IP: 
ntdll!PropertyLengthAsVariant+73
77f97704 cc               int     3

Pole FAULTING_IP zobrazuje ukazatel instrukce v době chyby.

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: 77f97704 (ntdll!PropertyLengthAsVariant+0x00000073)
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 3
   Parameter[0]: 00000000
   Parameter[1]: 00010101
   Parameter[2]: ffffffff

Pole EXCEPTION_RECORD zobrazuje záznam výjimky pro tento pád. Tyto informace lze zobrazit také pomocí příkazu .exr (Display Exception Record).

BUGCHECK_STR:  80000003

Pole BUGCHECK_STR zobrazuje kód výjimky. Název je nesprávné pojmenování – termín kontrola chyby ve skutečnosti označuje pád v režimu jádra. V ladění v uživatelském režimu se zobrazí kód výjimky – v tomto případě 0x80000003.

DEFAULT_BUCKET_ID:  APPLICATION_FAULT

Pole DEFAULT_BUCKET_ID zobrazuje obecnou kategorii selhání, ke kterým toto selhání patří.

PROCESS_NAME:  MyApp.exe

Pole PROCESS_NAME určuje název procesu, který vyvolal výjimku.

LAST_CONTROL_TRANSFER:  from 01050963 to 77f97704

Pole LAST_CONTROL_TRANSFER zobrazuje poslední volání zásobníku. V tomto případě kód na adrese 0x01050963 volal funkci na 0x77F97704. Tyto adresy můžete použít pomocí příkazu ln (List Nearest Symbols) a určit, v jakých modulech a funkcích se tyto adresy nacházejí.

STACK_TEXT:  
0006b9dc 01050963 00000000 0006ba04 000603fd ntdll!PropertyLengthAsVariant+0x73
0006b9f0 010509af 00000002 0006ba04 77e1a449 MyApp!FatalErrorBox+0x55 [D:\source_files\MyApp\util.c @ 541]
0006da04 01029f4e 01069850 0000034f 01069828 MyApp!ShowAssert+0x47 [D:\source_files\MyApp\util.c @ 579]
0006db6c 010590c3 000e01ea 0006fee4 0006feec MyApp!SelectColor+0x103 [D:\source_files\MyApp\colors.c @ 849]
0006fe04 77e11d0a 000e01ea 00000111 0000413c MyApp!MainWndProc+0x1322 [D:\source_files\MyApp\MyApp.c @ 1031]
0006fe24 77e11bc8 01057da1 000e01ea 00000111 USER32!UserCallWinProc+0x18
0006feb0 77e172b4 0006fee4 00000001 010518bf USER32!DispatchMessageWorker+0x2d0
0006febc 010518bf 0006fee4 00000000 01057c5d USER32!DispatchMessageA+0xb
0006fec8 01057c5d 0006fee4 77f82b95 77f83920 MyApp!ProcessQCQPMessage+0x3b [D:\source_files\MyApp\util.c @ 2212]
0006ff70 01062cbf 00000001 00683ed8 00682b88 MyApp!main+0x1e6 [D:\source_files\MyApp\MyApp.c @ 263]
0006ffc0 77e9ca90 77f82b95 77f83920 7ffdf000 MyApp!mainCRTStartup+0xff [D:\source_files\MyApp\crtexe.c @ 338]
0006fff0 00000000 01062bc0 00000000 000000c8 KERNEL32!BaseProcessStart+0x3d

Pole STACK_TEXT zobrazuje trasování zásobníku chybující komponenty.

FOLLOWUP_IP: 
MyApp!FatalErrorBox+55
01050963 5e               pop     esi

FOLLOWUP_NAME:  dbg

SYMBOL_NAME:  MyApp!FatalErrorBox+55

MODULE_NAME:  MyApp

IMAGE_NAME:  MyApp.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  383490a9

Když !analyze zjistí instrukce, která pravděpodobně způsobila chybu, zobrazí ji v poli FOLLOWUP_IP. Pole SYMBOL_NAME, MODULE_NAME, IMAGE_NAME a DEBUG_FLR_IMAGE_TIMESTAMP zobrazují symbol, modul, název obrázku a časové razítko obrázku odpovídající tomuto pokynu.

STACK_COMMAND:  .ecxr ; kb

Pole STACK_COMMAND zobrazuje příkaz použitý k získání STACK_TEXT. Tento příkaz můžete použít k opakování tohoto zobrazení trasování zásobníku nebo jej upravit, abyste získali související informace o zásobníku.

BUCKET_ID:  80000003_MyApp!FatalErrorBox+55

Pole BUCKET_ID zobrazuje konkrétní kategorii selhání, ke kterým patří aktuální selhání. Tato kategorie pomáhá ladicímu programu určit, jaké další informace se mají zobrazit ve výstupu analýzy.

Followup: dbg
---------

Informace o FOLLOWUP_NAME a polích následného sledování naleznete v části Pole pro sledování a soubor triage.ini.

Může se zobrazit celá řada dalších polí:

  • Pokud byl ovládací prvek převeden na neplatnou adresu, bude pole FAULTING_IP obsahovat tuto neplatnou adresu. V poli FAILED_INSTRUCTION_ADDRESS se místo pole FOLLOWUP_IP zobrazí deasemblovaný kód z této adresy, i když tato deasemblace bude pravděpodobně bezvýznamná. V této situaci budou pole SYMBOL_NAME, MODULE_NAME, IMAGE_NAME a DEBUG_FLR_IMAGE_TIMESTAMP odkazovat na volajícího této instrukce.

  • Pokud procesor selže, může se zobrazit pole SINGLE_BIT_ERROR, TWO_BIT_ERROR nebo POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Pokud se zdá, že došlo k poškození paměti, pole CHKIMG_EXTENSION určí příkaz rozšíření !chkimg , který by se měl použít k prozkoumání.

Příklad Kernel-Mode !analyze -v

V tomto příkladu je ladicí program připojený k počítači, který se právě zhroutil.

kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pagable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.

První prvek zobrazení zobrazuje kód kontroly chyb a informace o tomto typu kontroly chyb. Některé zobrazené texty se nemusí vztahovat na tuto konkrétní instanci. Další podrobnosti o každé kontrole chyb najdete v části Referenční informace o kódu kontroly chyb .

Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, value 0 = read operation, 1 = write operation
Arg4: f832035c, address which referenced memory

Dále se zobrazí parametry kontroly chyb. Každý z nich je následován popisem. Například třetí parametr je 1 a následující komentář vysvětluje, že to značí, že operace zápisu selhala.

## Debugging Details:


WRITE_ADDRESS:  00000004 Nonpaged pool

CURRENT_IRQL:  2

Několik dalších polí se liší v závislosti na povaze pádu. V tomto případě vidíme pole WRITE_ADDRESS a CURRENT_IRQL. Jedná se jednoduše o zopakování informací zobrazených v parametrech kontroly chyb. Porovnáním příkazu "Nonpaged pool" s textem kontroly chyby, který přečte "došlo k pokusu o přístup ke stránkovatelné (nebo zcela neplatné) adrese", vidíme, že adresa je neplatná. Neplatná adresa v tomto případě byla 0x00000004.

FAULTING_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

Pole FAULTING_IP zobrazuje ukazatel instrukce v době chyby.

DEFAULT_BUCKET_ID:  DRIVER_FAULT

Pole DEFAULT_BUCKET_ID zobrazuje obecnou kategorii selhání, ke kterým toto selhání patří.

BUGCHECK_STR:  0xD1

Pole BUGCHECK_STR zobrazuje kód kontroly chyb, který jsme už viděli. V některých případech jsou připojeny dodatečné informace pro třídění.

TRAP_FRAME:  f8950dfc -- (.trap fffffffff8950dfc)
.trap fffffffff8950dfc
ErrCode = 00000002
eax=81cc86dc ebx=81cc80e0 ecx=81e55688 edx=00000000 esi=81cc8028 edi=8052cf3c
eip=f832035c esp=f8950e70 ebp=f8950e90 iopl=0         nv up ei pl nz ac po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010216
USBPORT!USBPORT_BadRequestFlush+7c:
f832035c 894204           mov     [edx+0x4],eax     ds:0023:00000004=????????
.trap
Resetting default context

Pole TRAP_FRAME zobrazuje výjimkový rámec pro toto chybové ukončení. Tyto informace lze zobrazit také pomocí příkazu .trap (Display Trap Frame).

LAST_CONTROL_TRANSFER:  from f83206e0 to f832035c

Pole LAST_CONTROL_TRANSFER zobrazuje poslední volání zásobníku. V tomto případě kód na adrese 0xF83206E0 volal funkci na 0xF832035C. Pomocí příkazu ln (List Nearest Symbols) můžete určit, v jakém modulu a funkci se tyto adresy nacházejí.

STACK_TEXT:  
f8950e90 f83206e0 024c7262 00000000 f8950edc USBPORT!USBPORT_BadRequestFlush+0x7c
f8950eb0 804f5561 81cc8644 81cc8028 6d9a2f30 USBPORT!USBPORT_DM_TimerDpc+0x10c
f8950fb4 804f5644 6e4be98e 00000000 ffdff000 nt!KiTimerListExpire+0xf3
f8950fe0 8052c47c 8053cf20 00000000 00002e42 nt!KiTimerExpiration+0xb0
f8950ff4 8052c16a efdefd44 00000000 00000000 nt!KiRetireDpcList+0x31

Pole STACK_TEXT zobrazuje trasování zásobníku chybující komponenty.

FOLLOWUP_IP: 
USBPORT!USBPORT_BadRequestFlush+7c
f832035c 894204           mov     [edx+0x4],eax

Pole FOLLOWUP_IP zobrazuje demontáž instrukce, která pravděpodobně způsobila chybu.

FOLLOWUP_NAME:  usbtri

SYMBOL_NAME:  USBPORT!USBPORT_BadRequestFlush+7c

MODULE_NAME:  USBPORT

IMAGE_NAME:  USBPORT.SYS

DEBUG_FLR_IMAGE_TIMESTAMP:  3b7d868b

Pole SYMBOL_NAME, MODULE_NAME, IMAGE_NAME a DBG_FLR_IMAGE_TIMESTAMP zobrazují symbol, modul, obrázek a časové razítko obrázku odpovídající této instrukci (pokud je platné) nebo volajícímu této instrukce (pokud není).

STACK_COMMAND:  .trap fffffffff8950dfc ; kb

Pole STACK_COMMAND zobrazuje příkaz použitý k získání STACK_TEXT. Tento příkaz můžete použít k opakování tohoto zobrazení trasování zásobníku nebo k jeho úpravě k získání souvisejících informací o zásobníku.

BUCKET_ID:  0xD1_W_USBPORT!USBPORT_BadRequestFlush+7c

Pole BUCKET_ID zobrazuje konkrétní kategorii selhání, ke kterým patří aktuální selhání. Tato kategorie pomáhá ladicímu programu určit, jaké další informace se mají zobrazit ve výstupu analýzy.

Informace o FOLLOWUP_NAME a polích pro sledování naleznete v části Pole pro sledování a soubor triage.ini.

Může se zobrazit celá řada dalších polí:

  • Pokud byl ovládací prvek převeden na neplatnou adresu, bude pole FAULTING_IP obsahovat tuto neplatnou adresu. Místo pole FOLLOWUP_IP se v poli FAILED_INSTRUCTION_ADDRESS zobrazí disassemblovaný kód z této adresy, i když tento disassemblovaný kód bude pravděpodobně bezvýznamný. V této situaci budou pole SYMBOL_NAME, MODULE_NAME, IMAGE_NAME a DBG_FLR_IMAGE_TIMESTAMP odkazovat na volajícího této instrukce.

  • Pokud dojde k chybě procesoru, může se zobrazit položka SINGLE_BIT_ERROR, TWO_BIT_ERROR nebo POSSIBLE_INVALID_CONTROL_TRANSFER.

  • Pokud se zdá, že došlo k poškození paměti, pole CHKIMG_EXTENSION určí příkaz rozšíření !chkimg , který by se měl použít k prozkoumání.

  • Pokud v kódu ovladače zařízení došlo ke kontrole chyby, může se jeho název zobrazit v poli BUGCHECKING_DRIVER.

Pole Pro sledování a soubor triage.ini

V uživatelském režimu i v režimu jádra se v poli Sledování na displeji zobrazí informace o vlastníkovi aktuálního rámce zásobníku, pokud je to možné určit. Tyto informace se určují následujícím způsobem:

  1. Při použití rozšíření !analyze začíná ladicí program horním rámcem v zásobníku a určuje, zda je zodpovědný za chybu. Pokud tomu tak není, analyzuje se další snímek. Tento proces pokračuje, dokud se nenajde rámec, který může být chybný.

  2. Ladicí program se pokusí určit vlastníka modulu a funkce v tomto rámci. Pokud lze určit vlastníka, považuje se tento rámec za chybný.

  3. Pokud vlastníka nelze určit, ladicí program přejde k dalšímu rámci zásobníku a tak dále, dokud není vlastník určen (nebo zásobník není zcela prozkoumán). První rámec, jehož vlastník se v tomto hledání nachází, se považuje za chybný. Pokud je zásobník vyčerpán bez nalezených informací, nezobrazí se žádné pole Pro sledování.

  4. Vlastník chybového rámce se zobrazí v poli Pro sledování. Pokud se použije !analyze -v , budou pole FOLLOWUP_IP, SYMBOL_NAME, MODULE_NAME, IMAGE_NAME a DBG_FLR_IMAGE_TIMESTAMP odkazovat na tento rámec.

Aby se v poli Pro sledování zobrazovaly užitečné informace, musíte napřed vytvořit soubor triage.ini obsahující názvy modulů a vlastníků funkcí.

Soubor triage.ini by měl identifikovat vlastníky všech modulů, které by mohly mít chyby. Můžete použít informační řetězec místo skutečného vlastníka, ale tento řetězec nemůže obsahovat mezery. Pokud jste si jisti, že modul nebude vadit, můžete tento modul vynechat nebo označit, že by měl být vynechán. Je také možné určit vlastníky jednotlivých funkcí, což umožňuje procesu třídění dosáhnout ještě jemnější úrovně podrobnosti.

Podrobnosti o syntaxi souboru triage.ini naleznete v tématu Určení modulů a vlastníků funkcí.

Další !analýza technik

Pokud nedošlo k chybě nebo výjimce, zobrazí funkce !analyze velmi krátký text s aktuálním stavem cíle. V některých situacích můžete chtít vynutit provedení analýzy, jako by došlo k pádu systému. K provedení tohoto úkolu použijte !analyze -f .

Pokud došlo k výjimce v uživatelském režimu, ale domníváte se, že základním problémem je zablokované vlákno, přepněte aktuální vlákno na to, které prošetřujete, a následně použijte !analyze -hang. Toto rozšíření provede analýzu zásobníku vláken, která určí, jestli některá vlákna blokují jiná vlákna.

Pokud v režimu jádra došlo k zastavení z důvodu chyby, ale domníváte se, že hlavní problémem je zablokované vlákno, použijte !analyze -hang. Toto rozšíření prozkoumá zámky uchovávané systémem a prohledá řetěz front DPC a zobrazí všechny indikace zablokovaných vláken. Pokud se domníváte, že se jedná o problém zablokování prostředku v režimu jádra, použijte rozšíření !deadlock spolu s možností Detekce vzájemného zablokování u Ověřovatele ovladače.

Můžete také automaticky ignorovat známé problémy. Chcete-li to provést, musíte nejprve vytvořit soubor XML obsahující formátovaný seznam známých problémů. K načtení tohoto souboru použijte příponu !analyze -c -loadKnownIssuesFile . Když dojde k výjimce nebo přerušení, použijte rozšíření !analyze -c . Pokud výjimka odpovídá některému ze známých problémů, cíl bude pokračovat v provádění. Pokud cíl nepokračuje v provádění, můžete k určení příčiny problému využít !analyze -v.

Viz také

Další informace najdete v těchto tématech.

!analyze

Referenční informace ke kódu kontroly chyb

Analýza výpisu stavu po zhroucení systému pomocí ladicího nástroje systému Windows (WinDbg)

Analýza výpisového souboru Kernel-Mode pomocí WinDbg