vs2010 利用DMP文件、pdb文件查找release下的异常行号的方法
2018-01-12 10:45
597 查看
2018-01-12 创建人:Ruo_Xiao 开发环境:Windows7,VS2010,WinDbg 6.12。
一、源码
#include "stdafx.h" #include <windows.h> #include <DbgHelp.h> #pragma comment(lib,"Dbghelp.lib") static long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp); int _tmain(int argc, _TCHAR* argv[]) { ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback); int *pi = NULL; pi[3] = 5; //这里崩溃 return 0; } long __stdcall CrashInfocallback( _EXCEPTION_POINTERS *pexcp) { HANDLE hDumpFile = ::CreateFile( L"MEMORY.DMP", GENERIC_WRITE, //写入 0, //不共享 NULL, //默认安全属性 CREATE_ALWAYS, //总是创建 FILE_ATTRIBUTE_NORMAL, //默认属性 NULL //为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 ); } return 0; }
二、VS2010生成pdb文件
选择 项目 -> 工程名+属性,如下图所示。2. 进去
之后选择 配置属性 -> 连接器 -> 调试,如下图所示。
右面选项如下图所示:
上图中,“生成调试信息”为pdb文件生成与否的使能开关,“生成程序数据库文件”为该pdb文件的名字,默认即可。
三、生成DMP文件
两种方法:1. 利用资源管理器生成,即:程序崩溃之后会弹出“程序已停止运行对话框”,如下图所示:
此时在资源管理器“进程页”中找到该程序,右击,弹出的下拉菜单中找到“创建转出文件”选项,单击即可生成,不过该文件会生成在系统目录,人工找到即可。
2. 利用API在指定目录下生成,代码如上所示。
(1)SetUnhandledExceptionFilter
调用时机:当异常发生时,且程序不处于调试模式,则首先调用该函数。
参数:lpTopLevelExceptionFilter ,函数指针。
返回值:以前设置的回调函数。
(2)CreateFile
HANDLE CreateFile( LPCTSTR lpFileName, // 指向文件名的指针 DWORD dwDesiredAccess, // 访问模式(写 / 读) DWORD dwShareMode, // 共享模式,0就是不共享,反之共享。 LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向安全属性的指针 DWORD dwCreationDisposition, // 如何创建 DWORD dwFlagsAndAttributes, // 文件属性 HANDLE hTemplateFile // 用于复制文件句柄 );
返回值:若成功,则返回一个句柄,若失败,则返回INVALID_HANDLE_VALUE,即:-1。
(3)MINIDUMP_EXCEPTION_INFORMATION
作用:该结构体包含将要通过 MiniDumpWriteDump函数写入Minidup文件中的崩溃信息。
原型:
typedef struct _MINIDUMP_EXCEPTION_INFORMATION { DWORD ThreadId; PEXCEPTION_POINTERS ExceptionPointers; BOOL ClientPointers; } MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; ThreadId:抛出异常的线程ID。 ExceptionPointers:指向_EXCEPTION_POINTERS结构体的首地址,该结构体指向了异常时处理器上下文和独立于计算机的异常描述。 ClientPointers:指定崩溃的内存位置。若为TRUE,则崩溃位置位于客户端自己的地址空间中。若为FALSE,则崩溃内存位于调用该程序的地址空间中。
(4)MiniDumpWriteDump
作用:向指定的文件中写入用户自己的minidump信息。
原型:
BOOL MiniDumpWriteDump ( HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam ); hProcess:生成当前信息文件的进程的句柄。 ProcessId:生成当前信息对文件的进程的ID。 hFile:被写入信息的文件的句柄。 DumpType:向文件中写入的信息的类型,可查看 MINIDUMP_TYPE 。 ExceptionParam:指向MINIDUMP_EXCEPTION_INFORMATION结构体指针,若为NULL,则没有信息写入文件中。 UserStreamParam:指向 MINIDUMP_USER_STREAM_INFORMATION 结构体指针,若为NULL,则文件中没有用户指定的信息。 CallbackParam:指向MINIDUMP_CALLBACK_INFORMATION结构的指针,指定要接收扩展小型转储信息的回调例程。如果此参数的值为NULL,则不执行回调。
四、寻找崩溃位置
执行程序,发现程序崩溃,如下图所示:release目录下生成了对应的DMP文件,如下图所示。
打开WinDbg,依次进行下面操作:
File -> Symbol File Path -> 选择pdb文件存放路径。
File -> Image File Path -> 选择exe文件存放路径。
File -> Open Crash Dump -> 选择DMP文件存放路径。
最后会弹出WinDbg对崩溃文件的初步分析的结果,在下面的输入框中输入“!analyze -v”,意思是软件进行对崩溃文件进行分析,并显示出来,最后的结果如下所示:
PROCESS_NAME: TEST11.exe ADDITIONAL_DEBUG_TEXT: Use '!findthebuild' command to search for the target build information. If the build information is available, run '!findthebuild -s ; .reload' to set symbol path and load symbols. FAULTING_MODULE: 75750000 kernel32 DEBUG_FLR_IMAGE_TIMESTAMP: 5a5820bb MODULE_NAME: TEST11 ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx EXCEPTION_PARAMETER1: 00000001 EXCEPTION_PARAMETER2: 0000000c WRITE_ADDRESS: 0000000c FOLLOWUP_IP: TEST11!wmain+b [d:\test11\test11\test11.cpp @ 17] 003d100b c7050c00000005000000 mov dword ptr ds:[0Ch],5 MOD_LIST: <ANALYSIS/> FAULTING_THREAD: 0000265c BUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLS PRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCE DEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE LAST_CONTROL_TRANSFER: from 003d1205 to 003d100b STACK_TEXT: 0032fa40 003d1205 00000001 005f1b20 005f1b70 TEST11!wmain+0xb [d:\test11\test11\test11.cpp @ 17] 0032fa84 7576336a 7efde000 0032fad0 77d19902 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. 0032fa90 77d19902 7efde000 767ba0cb 00000000 kernel32!BaseThreadInitThunk+0x12 0032fad0 77d198d5 003d1326 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x63 0032fae8 00000000 003d1326 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36 STACK_COMMAND: ~0s; .ecxr ; kb FAULTING_SOURCE_CODE: 13: int _tmain(int argc, _TCHAR* argv[]) 14: { 15: ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback); 16: int *pi = NULL; > 17: pi[3] = 5; 18: return 0; 19: } 20: 21: long __stdcall CrashInfocallback( _EXCEPTION_POINTERS *pexcp) 22: { SYMBOL_STACK_INDEX: 0 SYMBOL_NAME: test11!wmain+b FOLLOWUP_NAME: MachineOwner IMAGE_NAME: TEST11.exe BUCKET_ID: WRONG_SYMBOLS FAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_TEST11.exe!wmain WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/TEST11_exe/0_0_0_0/5a5820bb/TEST11_exe/0_0_0_0/5a5820bb/c0000005/0000100b.htm?Retriage=1 Followup: MachineOwner
由上述信息中
Attempt to write to address 0000000c
代表写空指针。
0032fa40 003d1205 00000001 005f1b20 005f1b70 TEST11!wmain+0xb [d:\test11\test11\test11.cpp @ 17] 和 13: int _tmain(int argc, _TCHAR* argv[]) 14: { 15: ::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback); 16: int *pi = NULL; > 17: pi[3] = 5; 18: return 0; 19: } 20: 21: long __stdcall CrashInfocallback( _EXCEPTION_POINTERS *pexcp) 22: {
代表源码中第17行有异常。
上述就是简单地查找崩溃行数的方法。
五、源码工程
http://download.csdn.net/download/itworld123/10202793(完)
相关文章推荐
- VS2010下使用dmp文件和pdb文件定位程序异常代码行号的注意事项
- VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法
- vs2013或2012运行c语言出现:无法查找或打开 PDB 文件,解决方法
- vs2010下使用dmp文件和pdb文件调试时dump、exe和pdb三个文件要保持版本一致的原因
- opencv2.4.10+vs2010无法查找或打开 PDB 文件的问题
- VS“无法查找或打开PDB文件”的解决方法
- OpenCV:Visual Studio2013 出现"无法查找或打开PDB文件"解决方法
- 在vs2010中,输出当前文件路径与源文件当前行号的解决方法
- VS2010中配置C#Project不生成.vhost.exe和.pdb文件的方法
- Visual Studio "无法查找或打开PDB文件"解决方法
- 用vs2010生成驱动文件时,缺少db文件.pdb解决方法
- C++利用 _findfirst与_findnext查找文件的方法
- OpenCV:Visual Studio "无法查找或打开PDB文件"解决方法
- VS2010中配置C#Project不生成.vhost.exe和.pdb文件的方法
- VC下Release版程序崩溃异常捕捉与查找--map文件方式
- VS2010中配置C#Project不生成.vhost.exe和.pdb文件的方法
- vs2010调试时无法查找或打开 PDB 文件
- vs2010 程序出错异常后,自动生成dmp文件
- Visual Studio 不生成.vshost.exe和.pdb文件的方法和 在VS2010中去掉ipch和sdf文件方法
- 解决在VS2010下利用def文件使dll输出函数不改名的方法