4、查看所有线程堆栈:
~*kb如果有,则此堆栈为异常堆栈;
图示异常出现在3号线程中
注:如果查看到的堆栈都是显示如下的信息:
则表明需要将windbg切换到32位模式,才能分析,指令如下:
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;
除了上述的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
WinDbg 查找问题异常堆栈,堆栈跟踪UnhandledExceptionFilter
17.windbg-!cs、~~[TID](经典死锁)
注:切换当前的线程:
~0s 切换到0号线程
~3s 切换到3号线程