当程序异常时,使用windbg查看可能会看不到正确的堆栈,例如
ntdll!NtGetContextThread+0xc C/C++/ASM
> OperateFile!Content::copy_data+0x4c4 C/C++/ASM
ntdll!LdrpDecrementModuleLoadCountEx+0x3d C/C++/ASM
ntdll!LdrUnloadDll+0x4d C/C++/ASM
KERNELBASE!FreeLibrary+0x16 C/C++/ASM
dbgcore!WriteMiscInfo+0x324 C/C++/ASM
dbgcore!WriteDumpData+0x1f7 C/C++/ASM
dbgcore!MiniDumpProvideDump+0x46c C/C++/ASM
dbgcore!MiniDumpWriteDump+0x1dd C/C++/ASM
Base+0x54533 C/C++/ASM
Base+0x53e67 C/C++/ASM
Base+0x585fc C/C++/ASM
KERNELBASE!UnhandledExceptionFilter+0x1a0 C/C++/ASM
ntdll!__RtlUserThreadStart+0x3a10b C/C++/ASM
ntdll!_RtlUserThreadStart+0x1b C/C++/ASM
这里看到的是异常发生后的堆栈,异常的处理,是一个异常处理的上下文。
原先的上下文被保存,直接切换成了异常的上下文。因此在使用windbg查看的时候,需要使用如下的命令切换到异常前的上下文:
.exr -1
The .exr command displays the contents of an exception record.
然后kbn查看,显示如下:
00 00b5f01c 0062e955 00e81bc8 ce091c9e 00000000 0x0
01 00b5f24c 0066ac7b 00e81bc8 0067712d ffffffff OperateFile!OperateFile::JumpUrl2+0xc5 [c:\OperateFile\OperateFile.cpp @ 1046]
02 00b5fb10 006763c4 00000005 00deb038 00000000 OperateFile!main+0xa8b [c:\OperateFile\main.cpp @ 118]
03 00b5fb44 00675605 005f0000 00000000 00dc485e OperateFile!WinMain+0xe4
04 (Inline) -------- -------- -------- -------- OperateFile!invoke_main+0x1a [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 102]
05 00de1128 00000000 00000001 a3daa3c1 00000020 OperateFile!__scrt_common_main_seh+0xf8 [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
可以看到最后调用了0地址,导致崩溃,查看实际代码,是加载dll,并后获取地址func并调用,结果func是空,未做检查直接调用导致崩溃。