WinDbg重建堆棧

  某些情況下,抓取到dump分析到異常後,卻發現堆棧並不對,不能有效的定位到程序崩潰的地方,這個時候就需要重建一下堆棧。

  可以參考:HOW TO: Find the Problem Exception Stack When You Receive an UnhandledExceptionFilter Call in the Stack Trace 

  當然也可以試着用DebugDiag來分析,在“Recovered stack”中會顯示重建後的堆棧。

  下面是一個堆棧被破壞後的dump,分別用WinDbg重建和用DebugDiag分析後的結果:

0:003> k
ChildEBP RetAddr  
0764f630 75119171 USER32!NtUserWaitForInputIdle+0x15
0764f660 75892ce5 USER32!WaitForInputIdle+0x5a
0764f6fc 004e8b00 kernel32!WinExec+0xc4
0764f7d8 75850047 SDAMSDevMgmt!ExpFilter+0x152 [D:\WangWang\WIN2K\Common\..\include\StackWalker.h @ 339]
0764f860 772321d7 kernel32!UnhandledExceptionFilter+0x127
0764f868 772320b4 ntdll!__RtlUserThreadStart+0x62
0764f87c 77231f59 ntdll!_EH4_CallFilterFunc+0x12
0764f8a4 77206ab9 ntdll!_except_handler4+0x8e
0764f8c8 77206a8b ntdll!ExecuteHandler2+0x26
0764f8ec 77206a2d ntdll!ExecuteHandler+0x24
0764f978 771d0143 ntdll!RtlDispatchException+0x127
0764f978 00000000 ntdll!KiUserExceptionDispatcher+0xf
0:003> kb
ChildEBP RetAddr  Args to Child              
0764f630 75119171 00000fa8 00007530 00000000 USER32!NtUserWaitForInputIdle+0x15
0764f660 75892ce5 000007bc 00007530 0764f7cc USER32!WaitForInputIdle+0x5a
0764f6fc 004e8b00 0764f70c 00000000 6473746e kernel32!WinExec+0xc4
0764f7d8 75850047 0764f890 47ea2381 00000000 SDAMSDevMgmt!ExpFilter+0x152 [D:\WangWang\WIN2K\Common\..\include\StackWalker.h @ 339]
0764f860 772321d7 0764f890 772320b4 00000000 kernel32!UnhandledExceptionFilter+0x127
0764f868 772320b4 00000000 0764ffd4 771ec520 ntdll!__RtlUserThreadStart+0x62
0764f87c 77231f59 00000000 00000000 00000000 ntdll!_EH4_CallFilterFunc+0x12
0764f8a4 77206ab9 fffffffe 0764ffc4 0764f9e0 ntdll!_except_handler4+0x8e
0764f8c8 77206a8b 0764f990 0764ffc4 0764f9e0 ntdll!ExecuteHandler2+0x26
0764f8ec 77206a2d 0764f990 0764ffc4 0764f9e0 ntdll!ExecuteHandler+0x24
0764f978 771d0143 0164f990 0764f9e0 0764f990 ntdll!RtlDispatchException+0x127
0764f978 00000000 0164f990 0764f9e0 0764f990 ntdll!KiUserExceptionDispatcher+0xf
0:003> kP
ChildEBP RetAddr  
0764f630 75119171 USER32!NtUserWaitForInputIdle+0x15
0764f660 75892ce5 USER32!WaitForInputIdle+0x5a
0764f6fc 004e8b00 kernel32!WinExec+0xc4
0764f7d8 75850047 SDAMSDevMgmt!ExpFilter(
			struct _EXCEPTION_POINTERS * pExp = 0x0764f890)+0x152 [D:\WangWang\WIN2K\Common\..\include\StackWalker.h @ 339]
0764f860 772321d7 kernel32!UnhandledExceptionFilter+0x127
0764f868 772320b4 ntdll!__RtlUserThreadStart+0x62
0764f87c 77231f59 ntdll!_EH4_CallFilterFunc+0x12
0764f8a4 77206ab9 ntdll!_except_handler4+0x8e
0764f8c8 77206a8b ntdll!ExecuteHandler2+0x26
0764f8ec 77206a2d ntdll!ExecuteHandler+0x24
0764f978 771d0143 ntdll!RtlDispatchException+0x127
0764f978 00000000 ntdll!KiUserExceptionDispatcher+0xf
0:003> dd 0764f890
0764f890  0764f990 0764f9e0 771ec530 00000001
0764f8a0  007cdea8 0764f8c8 77206ab9 fffffffe
0764f8b0  0764ffc4 0764f9e0 0764f964 0764fedc
0764f8c0  77206acd 0764ffc4 0764f978 77206a8b
0764f8d0  0764f990 0764ffc4 0764f9e0 0764f964
0764f8e0  77231ecd 00000000 0764f990 0764ffc4
0764f8f0  77206a2d 0764f990 0764ffc4 0764f9e0
0764f900  0764f964 77231ecd 09023a40 0764f990
0:003> .cxr 0764f9e0
eax=09023a40 ebx=08540020 ecx=0000000c edx=00000000 esi=08540020 edi=09023a40
eip=755aa048 esp=0764fe44 ebp=0764fe4c iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
msvcrt!__ascii_strnicmp+0x86:
755aa048 660f6f06        movdqa  xmm0,xmmword ptr [esi] ds:002b:08540020=????????????????????????????????
0:003> k
  *** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr  
0764fe4c 755aa00b msvcrt!__ascii_strnicmp+0x86
0764fe5c 72a83ae4 msvcrt!_VEC_memcpy+0x52
0764fe7c 0048f8cd MFC42u!CFixedAlloc::Free+0x2a
0764fe98 004c3659 SDAMSDevMgmt!CBufferListItem::AddData+0x6e [D:\WangWang\WIN2K\Common\RingStream.cpp @ 876]
0764feb4 004dae64 SDAMSDevMgmt!CSDAMSMsgConvertor::PushBuffer+0x58 [D:\WangWang\WIN2K\COMMON\SDAMSMsgConvertor.cpp @ 116]
0764fee8 004f210d SDAMSDevMgmt!SDAMTransferThread::OnReceive+0x119 [D:\WangWang\WIN2K\SDAMSDevMgmt\SDAMTransferThread.cpp @ 111]
0764ff18 004f2063 SDAMSDevMgmt!CTCPServerThread::ProcessMsg+0x5f [D:\WangWang\WIN2K\Common\TCPServerThread.cpp @ 482]
0764ff48 755b1287 SDAMSDevMgmt!CTCPServerThread::_ServerWorkThread+0xec [D:\WangWang\WIN2K\Common\TCPServerThread.cpp @ 452]
0764ff80 755b1328 msvcrt!_endthreadex+0x44
0764ff88 758133ca msvcrt!_endthreadex+0xce
0764ff94 771f9ed2 kernel32!BaseThreadInitThunk+0xe
0764ffd4 771f9ea5 ntdll!__RtlUserThreadStart+0x70
0764ffec 00000000 ntdll!_RtlUserThreadStart+0x1b


  下面是DebugDiag分析後的結果片段:

  附上_EXCEPTION_POINTERS的定義,結合上面WinDbg分析過程來看。注意kb和kP的區別,kb中kernel32!UnhandledExceptionFilter第一個Args to Child爲0764f890,就是SDAMSDevMgmt!ExpFilter第一個參數的地址(kP中struct _EXCEPTION_POINTERS * pExp = 0x0764f890),爲一個_EXCEPTION_POINTERS結構,然後就可以用.cxr查看此結構中PCONTEXT的值。

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章