1. 程式人生 > >windbg分析dump操作流程

windbg分析dump操作流程

1、載入pdb:
.reload /i /f

2、檢視pdb是否載入成功:
lm

3、自動分析指令(通常分析出的是主執行緒的堆疊)
!analyze -v

此時通過分析出的堆疊去找有無kernel32!UnhandledExceptionFilter資訊
如果有,則此堆疊(主執行緒堆疊)為異常堆疊;
如果沒有,則需檢視所有執行緒堆疊:

4、檢視所有執行緒堆疊:

~*kb

同理去找有無kernel32!UnhandledExceptionFilter資訊堆疊

如果有,則此堆疊為異常堆疊;


圖示異常出現在3號執行緒中

注:如果檢視到的堆疊都是顯示如下的資訊:


則表明需要將windbg切換到32位模式,才能分析,指令如下:

  • .load wow64exts
  • !sw

5、找到異常堆疊分析,切換到異常堆疊的執行緒ID;
   檢視該執行緒(3號執行緒)的堆疊:
eg:
0:000> ~3s


6、dd [Args to Child的第一個引數(該例子中是0329e7b0)] (指令是d, 第二個d表示是DWORD:雙字,表示4位元組資料格式)
   第一個引數指向了_EXCEPTION_POINTERS結構體

注:_EXCEPTION_POINTERS的定義如下:

typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;


eg:
0:003> dd 0329e7b0
00000000`0329e7b0  0329f3f0 00000000 0329ef00 00000000
00000000`0329e7c0  76f60000 00000000 0329f3f0 00000000
00000000`0329e7d0  00000000 00000000 76f8c541 00000000
00000000`0329e7e0  0329a000 00000000 76f89d2d 00000000
00000000`0329e7f0  032a0000 00000000 0329f830 00000000
00000000`0329e800  0329f830 00000000 770a2dd0 00000000
00000000`0329e810  0329e8b0 00000000 76f791cf 00000000
00000000`0329e820  032a0000 00000000 76f4dda0 00000000


7、.cxr [dd結果的第二個引數,此例中為0329ef00]  -重建堆疊(檢視結構體中的PCONTEXT成員)


可以看到他的錯誤堆疊資訊和windows捕捉到的是一致的


8、.exr [dd結果的第一個引數,此例中為0329f3f0] (檢視結構體中的 PEXCEPTION_RECORD成員)





9、kv 檢視程式崩潰前呼叫的最後堆疊資訊 【需執行完上述8步後】



如果在上述第四步後仍未發現沒有任何異常錯誤堆疊資訊,此時有可能是執行緒之間死鎖了
可通過以下指令檢視
5、!locks 【需載入相應的windows pdb檔案】

6、然後通過死鎖的執行緒id:7d8去 ~*kb裡面尋找該執行緒的堆疊

除了上述的UnhandledExceptionFilter異常和死鎖的現象,還有一種_except_handler異常的情況,其處理流程和UnhandledExceptionFilter類似,具體如下:

_except_handler函式的情況


1.有些情況下堆疊中沒有UnhandledExceptionFilter,而只有_except_handler函式,這個是SEH異常處理函式。函式原型:EXCEPTION_DISPOSITION __cdecl _except_handler( 
                         struct _EXCEPTION_RECORD *ExceptionRecord,
                         void * EstablisherFrame,
                         struct _CONTEXT *ContextRecord,
                         void * DispatcherContext); 
這個函式的第一個引數是一個指向 EXCEPTION_RECORD 結構的指標。這個結構在WINNT.H中定義,如下所示: 
typedef struct _EXCEPTION_RECORD {
   DWORD ExceptionCode;
   DWORD ExceptionFlags;
   struct _EXCEPTION_RECORD *ExceptionRecord;
   PVOID ExceptionAddress;
   DWORD NumberParameters;
   DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD; 
_except_handler 函式的第二個引數是一個指向establisher幀結構的指標。
_except_handler 回撥函式的第三個引數是一個指向 CONTEXT 結構的指標。
typedef struct _CONTEXT
{
    DWORD ContextFlags;
    DWORD Dr0;
    DWORD Dr1;
    DWORD Dr2;
    DWORD Dr3;
    DWORD Dr6;
    DWORD Dr7;
    FLOATING_SAVE_AREA FloatSave;
    DWORD SegGs;
    DWORD SegFs;
    DWORD SegEs;
    DWORD SegDs;
    DWORD Edi;
    DWORD Esi;
    DWORD Ebx;
    DWORD Edx;
    DWORD Ecx;
    DWORD Eax;
    DWORD Ebp;
    DWORD Eip;
    DWORD SegCs;
    DWORD EFlags;
    DWORD Esp;
    DWORD SegSs;
} CONTEXT; 
_except_handler 回撥函式的第四個引數被稱為DispatcherContext。


2.分析dump檔案時,在命令提示符處鍵入 ~*kb 要列出所有程序中執行緒。


3.標識進行函式呼叫的執行緒 Kernel32!_except_handler。 它看起來類似於以下內容:
   9  Id: 918.117c Suspend: 2 Teb: 7ffd8000 Unfrozen
ChildEBP RetAddr  Args to Child            
085df400 7c9232a8 085df4ec 085dffdc 085df50c kernel32!_except_handler3+0x61
085df424 7c92327a 085df4ec 085dffdc 085df50c ntdll!ExecuteHandler2+0x26
085df4d4 7c92e48a 00000000 085df50c 085df4ec ntdll!ExecuteHandler+0x24

4.切換到該執行緒 (在此示例中,執行緒是"~ 9s")。

5.Kernel32! !_except_handler第一個引數 dword 值表示異常記錄。 若要獲取有關異常的型別的資訊,請在命令提示符處執行以下:
 .exr first DWORD from step 5
0:009> .exr 085df4ec
ExceptionAddress: 7c812afb (kernel32!RaiseException+0x00000053)  
ExceptionCode: e06d7363 (C++ EH exception) 
ExceptionFlags: 00000001
NumberParameters: 3  
Parameter[0]: 19930520  
Parameter[1]: 085df874  
Parameter[2]: 006c010c

6.Kernel32! !_except_handler第三個引數 dword 值是上下文記錄。 要獲取的上下文資訊,請在命令提示符處執行以下: 
.cxr second DWORD from step 6
0:009> .cxr 085df50c
eax=085df7dc ebx=00005d34 ecx=00000000 edx=01240608 esi=085df864 edi=00100000eip=7c812afb esp=085df7d8 ebp=085df82c iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206kernel32!RaiseException+0x53:7c812afb 5e              pop     esi

 7.執行 kv 命令以獲得實際的異常的呼叫堆疊。 這可以幫助您識別可能不具有被正確處理過程中的實際問題 
0:009> kv
ChildEBP RetAddr  Args to Child          
WARNING: Stack unwind information not available. Following frames may be wrong.
09a8fa2c 780119ab 09a8fad4 00000000 09a8faa8 MSVCRT!strnicmp+0x92
09a8fa40 7801197c 09a8fad4 00000000 6d7044fd MSVCRT!stricmp+0x3c
09a8fa80 6e5a6ef6 09a8fad4 2193d68d 00e5e298 MSVCRT!stricmp+0xd

參考博文: