失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > VS下使用dmp文件和pdb文件定位程序异常代码行号的注意事项

VS下使用dmp文件和pdb文件定位程序异常代码行号的注意事项

时间:2021-10-22 04:49:57

相关推荐

VS下使用dmp文件和pdb文件定位程序异常代码行号的注意事项

-01-12 创建人:Ruo_Xiao-01-15 修改人:Ruo_Xiao添加为dump、exe和pdb版本保持一致的原因。

一、minidump文件

崩溃转储是创建一个应用程序崩溃瞬间的状态镜像。初代的转储文件是记录了进程的虚拟空间中全部内容,但是这样的文件非常大,而且对于不太熟练使用的人员来说冗余信息太多。xp之后,MicroSoft发明了“minidump”的转储技术,即:小型的,只是包含了必要的线程调用堆栈等信息文件。该文件很小,很容易通过网络发送,同时也可以定制该文件记录的信息,非常的灵活。生成minidump的函数包含在DbgHelp.dll中。

二、pdb文件

后续加入!

三、注意事项

1、 exe文件、dmp文件和pdb文件必须保持一致!

在上篇博客中,我们简单的介绍了如何用dmp文件和pdb文件定位代码中崩溃位置。链接如下:

/itworld123/article/details/79041500

上述能够成功定位的一个前提是exe文件、dmp文件和pdb文件都是同时生成的,即:exe文件和pdb文件同时生成,dmp文件是由当前exe生成的。若生成崩溃信息之后,又重新编译了exe,与此同时也重新生成了pdb文件,那么即使代码没有任何改动,此时WinDbg也没有办法进行代码行号定位了,显示的信息如下:

WRITE_ADDRESS: 0000000c FOLLOWUP_IP: TEST11+100b012b100b c7050c00000005000000 mov dword ptr ds:[0Ch],5MOD_LIST: <ANALYSIS/>FAULTING_THREAD: 0000139cBUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 746b336a to 012b100bSTACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong.0029f934 746b336a 7efde000 0029f980 77139902 TEST11+0x100b0029f940 77139902 7efde000 7735f926 00000000 kernel32!BaseThreadInitThunk+0x120029f980 771398d5 012b132d 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x630029f998 00000000 012b132d 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbSYMBOL_STACK_INDEX: 0SYMBOL_NAME: TEST11+100bFOLLOWUP_NAME: MachineOwnerIMAGE_NAME: TEST11.exeBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_TEST11.exe!UnknownWATSON_STAGEONE_URL: /StageOne/TEST11_exe/0_0_0_0/5a58a12a/TEST11_exe/0_0_0_0/5a58a12a/c0000005/0000100b.htm?Retriage=1Followup: MachineOwner

上述信息大家可以看到,定位源码的功能已经消失了。

2、关闭代码优化功能。

#include "stdafx.h"#include <windows.h>#include <DbgHelp.h>#pragma comment(lib,"Dbghelp.lib")static long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp);void ErrorFun(int *p){p[2] = 10; //这里崩溃}int _tmain(int argc, _TCHAR* argv[]){::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);int *pi = NULL; ErrorFun(pi); return 0;}long __stdcall CrashInfocallback( _EXCEPTION_POINTERS *pexcp){HANDLE hDumpFile = ::CreateFile(L"MEMORY.DMP",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if( hDumpFile != INVALID_HANDLE_VALUE){MINIDUMP_EXCEPTION_INFORMATION dumpInfo;dumpInfo.ExceptionPointers = pexcp;dumpInfo.ThreadId = ::GetCurrentThreadId();dumpInfo.ClientPointers = TRUE;::MiniDumpWriteDump(::GetCurrentProcess(),::GetCurrentProcessId(),hDumpFile,MiniDumpNormal,&dumpInfo,NULL,NULL);}::CloseHandle(hDumpFile);return 0;}

上述代码在没有关闭代码优化功能的情况下,按照上篇博客的方法,生成的信息如下:

WRITE_ADDRESS: 00000008 FOLLOWUP_IP: TEST11!wmain+b [d:\huawei\projects\test11\test11\test11.cpp @ 22]013e100b c705080000000a000000 mov dword ptr ds:[8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 00000814BUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 013e120c to 013e100bSTACK_TEXT: 0038f9cc 013e120c 00000001 00032888 00033a40 TEST11!wmain+0xb [d:\huawei\projects\test11\test11\test11.cpp @ 22]0038fa10 746b336a 7efde000 0038fa5c 77139902 TEST11!__tmainCRTStartup+0x122 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 552]WARNING: Stack unwind information not available. Following frames may be wrong.0038fa1c 77139902 7efde000 775e96bf 00000000 kernel32!BaseThreadInitThunk+0x18fa5c 771398d5 013e132d 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x630038fa74 00000000 013e132d 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbFAULTING_SOURCE_CODE: 18: int _tmain(int argc, _TCHAR* argv[])19: {20: ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);21: int *pi = NULL; > 22: ErrorFun(pi); 23: return 0;24: }25: 26: long __stdcall CrashInfocallback( _EXCEPTION_POINTERS *pexcp)27: {SYMBOL_STACK_INDEX: 0SYMBOL_NAME: test11!wmain+bFOLLOWUP_NAME: MachineOwnerIMAGE_NAME: TEST11.exeBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_TEST11.exe!wmainWATSON_STAGEONE_URL: /StageOne/TEST11_exe/0_0_0_0/5a58a3c4/TEST11_exe/0_0_0_0/5a58a3c4/c0000005/0000100b.htm?Retriage=1Followup: MachineOwner

大家可以发现,WinDbg确实定位到了源码位置,但是仅仅是函数外面,没有进去。

后来上网查了很多资料,最后隐约感觉到可能是Release代码优化的原因,所以当我关闭代码优化的时候,成功地定位到了真正的位置。信息如下:

WRITE_ADDRESS: 00000008 FOLLOWUP_IP: TEST11!ErrorFun+6 [d:\huawei\projects\test11\test11\test11.cpp @ 15]00df1006 c740080a000000 movdword ptr [eax+8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 000013acBUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 00df102f to 00df1006STACK_TEXT: 0028fbfc 00df102f 00000000 00000000 0028fc50 TEST11!ErrorFun+0x6 [d:\huawei\projects\test11\test11\test11.cpp @ 15]0028fc0c 00df1232 00000001 003b2888 003b3a40 TEST11!wmain+0x1f [d:\huawei\projects\test11\test11\test11.cpp @ 22]0028fc50 746b336a 7efde000 0028fc9c 77139902 TEST11!__tmainCRTStartup+0x122 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 552]WARNING: Stack unwind information not available. Following frames may be wrong.0028fc5c 77139902 7efde000 77413872 00000000 kernel32!BaseThreadInitThunk+0x120028fc9c 771398d5 00df1353 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x630028fcb4 00000000 00df1353 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbFAULTING_SOURCE_CODE: 11: static long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp);12: 13: void ErrorFun(int *p)14: {> 15: p[2] = 10; //?a¨¤?¡À¨¤¨¤¡ê16: }17: 18: int _tmain(int argc, _TCHAR* argv[])19: {20: ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);SYMBOL_STACK_INDEX: 0SYMBOL_NAME: test11!ErrorFun+6FOLLOWUP_NAME: MachineOwnerIMAGE_NAME: TEST11.exeBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_TEST11.exe!ErrorFunWATSON_STAGEONE_URL: /StageOne/TEST11_exe/0_0_0_0/5a58a4b0/TEST11_exe/0_0_0_0/5a58a4b0/c0000005/00001006.htm?Retriage=1Followup: MachineOwner

拓展:VS关闭代码优化的方法:

项目 -> 工程名 + 属性

弹出如下图所示的框:

对“优化”选择“已禁用”,默认为“使速度最大化”,确定之后,重新编译程序即可。

四、总结

禁用程序优化功能。exe、pdb和dmp文件保持一致。

解释:exe文件和pdb文件同时生成,dmp文件是由当前exe生成的。

五、源码

/download/itworld123/10203098

如果觉得《VS下使用dmp文件和pdb文件定位程序异常代码行号的注意事项》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。