第一种情况
在用windbg打开dmp文件时会出现:
1、运行!analyze -v提示以下内容
0:124> !analyze -v
*******************************************************************************
* *
* Exception Analysis *
* *
*******************************************************************************
*** WARNING: symbols timestamp is wrong 0x92f57b1a 0xe7ccf5fb for kernel32.dll
*** WARNING: symbols timestamp is wrong 0xefa6b327 0x2a6e112d for user32.dll
WARNING: KERNELBASE overlaps oleaut32
WARNING: KERNELBASE overlaps bcryptPrimitives
WARNING: KERNELBASE overlaps cfgmgr32
WARNING: KERNELBASE overlaps Wldap32
*** WARNING: symbols timestamp is wrong 0x4809adf2 0xc830c52d for KERNELBASE.dll
KEY_VALUES_STRING: 1
Key : Analysis.CPU.Sec
Value: 5
Key : Analysis.DebugAnalysisProvider.CPP
Value: Create: 8007007e on A016486-PC
Key : Analysis.DebugData
Value: CreateObject
Key : Analysis.DebugModel
Value: CreateObject
Key : Analysis.Elapsed.Sec
Value: 5
Key : Analysis.Memory.CommitPeak.Mb
Value: 79
Key : Analysis.System
Value: CreateObject
Key : Timeline.OS.Boot.DeltaSec
Value: 9832
Key : Timeline.Process.Start.DeltaSec
Value: 8919
NTGLOBALFLAG: 40000000
APPLICATION_VERIFIER_FLAGS: 0
CONTEXT: (.ecxr)
rax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=00007ff99ddf0910 rsp=000000002786fc38 rbp=0000000000000000
r8=0000000000000000 r9=00007ff99de1ca00 r10=0000000000000000
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000200
ntdll!DbgBreakPoint:
00007ff9`9ddf0910 cc int 3
Resetting default scope
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00007ff99ddf0910 (ntdll!DbgBreakPoint)
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 1
Parameter[0]: 0000000000000000
PROCESS_NAME: test.exe
ERROR_CODE: (NTSTATUS) 0x80000003 - { }
EXCEPTION_CODE_STR: 80000003
EXCEPTION_PARAMETER1: 0000000000000000
STACK_TEXT:
00000000`2786fc38 00007ff9`9de1ca4e : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!DbgBreakPoint
00000000`2786fc40 00007ff9`9dda265f : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!DbgUiRemoteBreakin+0x4e
00000000`2786fc70 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2f
SYMBOL_NAME: ntdll!DbgBreakPoint+0
MODULE_NAME: ntdll
IMAGE_NAME: ntdll.dll
STACK_COMMAND: ~124s ; .ecxr ; kb
FAILURE_BUCKET_ID: BREAKPOINT_80000003_ntdll.dll!DbgBreakPoint
OSPLATFORM_TYPE: x64
OSNAME: Windows 8
FAILURE_ID_HASH: {1d20f983-583a-5d58-a854-5c812a87c587}
Followup: MachineOwner
---------
可以看到
1、执行一下.load wow64exts、!sw
2、执行一下STACK_COMMAND字段的命令
这里好像没有有用的信息,所以还是看看线程吧。
3、执行一下~*kv命令
直接在打印的线程信息中查找一下UnhandledExceptionFilter或CustomUnhandledExceptionFilter
1、查找到
切换到对应的线程,如20号线程,执行~20s,kv
0:000> ~20s
eax=8000000d ebx=09c4e37c ecx=d5b97eaf edx=00ec0000 esi=00000000 edi=09c4e368
eip=772346bc esp=09c4e2fc ebp=09c4e328 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
ntdll!NtWaitForAlertByThreadId+0xc:
772346bc c20800 ret 8
0:020> kv
# ChildEBP RetAddr Args to Child
00 09c4e2f8 7721f909 695d0d28 00000000 695d0d24 ntdll!NtWaitForAlertByThreadId+0xc (FPO: [2,0,0])
01 09c4e328 7721f65d 00000000 00000000 695d0d24 ntdll!RtlpWaitOnAddressWithTimeout+0x64 (FPO: [Non-Fpo])
02 09c4e3c8 772000ca ffffffff 8000000d 09c4e460 ntdll!RtlpWaitOnCriticalSection+0x18d (FPO: [Non-Fpo])
03 09c4e400 771fff19 051f0000 09c4e444 69552c82 ntdll!RtlpEnterCriticalSectionContended+0x1aa (FPO: [Non-Fpo])
04 09c4e40c 69552c82 695d0d24 e6b74d88 00000001 ntdll!RtlEnterCriticalSection+0x49 (FPO: [1,0,0])
WARNING: Stack unwind information not available. Following frames may be wrong.
05 09c4e444 76fad41c ffffffff 051f0000 09c4e4b7 test+0x12c82
06 09c4e464 6da4d5cd ffffffff 051f0000 09c4e4b7 KERNELBASE!ReadProcessMemory+0x1c (FPO: [Non-Fpo])
07 09c4e48c 6da4d860 ffffffff 051f0000 00000000 dbgcore!Win32LiveSystemProvider::ReadAllVirtual+0x2d (FPO: [Non-Fpo])
08 09c4e4c8 6da56a1b ffffffff 051ef824 00000000 dbgcore!Win32LiveSystemProvider::GetValidVirtualRange+0x110 (FPO: [6,5,4])
09 09c4e54c 6da51941 00000002 00000000 051ef834 dbgcore!GenAddMemoryBlock+0x14e (FPO: [Non-Fpo])
0a 09c4e598 6da552bb 01ba27b8 051ef834 00000000 dbgcore!GenAddThreadStack+0x14c (FPO: [Non-Fpo])
0b 09c4e738 6da4ac41 09c4e7ac 09c4e794 01ba0840 dbgcore!GenGetProcessInfo+0x8d5 (FPO: [Non-Fpo])
0c 09c4e950 6da4b51d 01ba05e8 01ba0840 01ba05b8 dbgcore!MiniDumpProvideDump+0x332 (FPO: [Non-Fpo])
0d 09c4e9e8 00104364 ffffffff 000025ec 00000ca4 dbgcore!MiniDumpWriteDump+0x1dd (FPO: [7,25,4])
0e 09c4ec70 00104867 0214b1b8 829feb30 09c4ec8c test+0x44364
0f 09c4ec9c 00103b00 829feabc 09c4ecf8 0000001c test+0x44867
10 09c4ed10 7704ea12 09c4eddc c6be1cbc 00000000 test+0x43b00
11 09c4edac 77264883 09c4eddc 77236fc2 09c4f91c KERNELBASE!UnhandledExceptionFilter+0x192 (FPO: [Non-Fpo])
12 09c4f91c 77227a4e ffffffff 77248a3a 00000000 ntdll!__RtlUserThreadStart+0x3ce34
13 09c4f92c 00000000 6c73813d 07b8ada8 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
显示一下UnhandledExceptionFilter或CustomUnhandledExceptionFilter第一个参数的内容,这个参数主要是EXCEPTION_POINTERS 结构,如下:
接着显示一下异常记录
0:020> dd 09c4eddc
09c4eddc 09c4ef1c 09c4ef6c 772cc850 00000001
09c4edec 772cc840 001cc2f0 09c4ee14 7723ad40
09c4edfc 772eb370 77234b50 09c4ef1c 09c4f90c
09c4ee0c 09c4ef6c 09c4eea4 09c4ee38 772488c2
09c4ee1c 09c4ef1c 09c4f90c 09c4ef6c 09c4eea4
09c4ee2c 09c4f3f8 772488e0 09c4f90c 09c4ef04
09c4ee3c 77248894 09c4ef1c 09c4f90c 09c4ef6c
09c4ee4c 09c4eea4 7723ad20 09c4f90c 09c4ef1c
0:020> .exr 09c4ef1c
ExceptionAddress: 6b319e71 (testDll+0x00039e71)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 013c3e9e
Attempt to read from address 013c3e9e
如上,这时候就可以加载一下对应的pdb,如这里需要加载testDll.dll的pdb。加载完pdb之后获取一下异常上下文
接着可以双击前面的序号,就可以显示对应函数的变量以及值
这样就可以确认是否是对应的值有问题了。
第二种情况
主要是记录下在工作中遇到的一个问题
使用windbg执行!analyze -v之后,根据提示获取的堆栈信息如下:
BUCKET_ID:APPLICATION_FAULT_NULL_CLASS_PTR_READ
根据代码行号去检查对应的源代码,发现dump的提示信息和代码的map结构不一致,判断这个dump的堆栈信息不可信。。
首先尝试使用方法1中的方法处理,发现获取的堆栈信息是一样的,没有价值。。只能另想它法。。
怀疑是程序中其他地方内存异常导致的程序崩溃,堆栈是显示这个map,但是实际并不是map引起的,因此检查下map对象所在类的所有成员变量,发现没有什么问题。。
接着检查下近期代码的修改,发现在Start的时候启动的线程数是4个,但是在Stop时停止的线程数是8个!!!进而导致线程类的对象指针有为NULL的情况,还调用了对应的线程类的成员方法,因此导致的崩溃(Stop的时候将线程数改成4,再次测试验证就没有崩溃了)。。
因此在这里总结一下,以后遇到的话处理的思路
1、检查dump提示的堆栈等是否和代码匹配上
2、能匹配上就检查下提示的堆栈结构等
3、匹配不上则可优先检查dump提示类的成员变量的使用、线程数等是否一致、其他原因待定
如strcpy或者memcpy是否出现越界访问等、非单线程的情况下检查前后线程数是否一致等
备注:这种崩溃通过分析dump文件并不能准确定位到具体原因,只能一行一行地分析代码,因此我们平常写代码对数组的赋值、多线程的使用等要格外小心,或者review的时候要十分的仔细。。这种崩溃发生的话,堆栈信息没有用,而且调试的话可能也不能走到对应的代码行,需要花大量的时间去分析代码(这个线程数花了我4天的时间。。当然可能是我脑袋不机灵的原因)。。