VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法
一、基礎鏈接
http://blog.csdn.net/itworld123/article/details/79041500
http://blog.csdn.net/itworld123/article/details/79047788
http://blog.csdn.net/itworld123/article/details/79061296
二、源碼
1、DLL代碼(工程1)
#pragma once#ifdef __XError_Export__#define __XError_DLL__ _declspec(dllexport) #else#define __XError_DLL__ _declspec(dllimport) #endifclass __XError_DLL__ XError { public:XError(void);~XError(void); public:void ErrorFun(int *p); }; -------------------------------------------------------------- void XError::ErrorFun(int *p) {p[2] = 10; //崩潰位置,源碼中顯示第16行 }2、測試代碼(工程2)
#include "stdafx.h" #include "source/ErrorDLL/XError.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);XError X;int *p = NULL;X.ErrorFun(p); //調(diào)用dll中含有崩潰代碼的函數(shù),源碼第19行return 0; }long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp) {//創(chuàng)建 Dump 文件HANDLE hDumpFile = ::CreateFile(L"MEMORY.DMP",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if( hDumpFile != INVALID_HANDLE_VALUE){//Dump信息MINIDUMP_EXCEPTION_INFORMATION dumpInfo;dumpInfo.ExceptionPointers = pexcp;dumpInfo.ThreadId = GetCurrentThreadId();dumpInfo.ClientPointers = TRUE;//寫入Dump文件內(nèi)容::MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hDumpFile,MiniDumpNormal,&dumpInfo,NULL,NULL);}return 0; }三、要點
四、定位dll文件中崩潰位置行號步驟
1、修改工程1的pdb文件生成目錄,如下所示。
項目 -> 工程名 + 屬性,按照下圖修改
將“生成程序數(shù)據(jù)庫文件”改為上圖所示,意思是dll對應的pdb文件的生成路徑為C盤PDB文件下,名字為工程名.pdb,同時該路徑會被記錄在對應的PE文件中(重要!!!)。
2、將生成的dll文件copy到exe所在的目錄下,如下所示:
雙擊exe,因為程序崩潰自動生成了“MEMORY.DMP”文件,如下圖所示:
3、打開WinDbg軟件,操作步驟如下:
(1)File -> Image File Path 下圖所示的框:
選中“Browse…”按鈕,選擇TEST1.exe,如下圖所示:
(2)File -> Open Crash Dump… 選擇剛才生成的"MEMORY.DMP"文件。
(3)之后軟件會彈出命令行窗口,如下圖所示:
在下面命令行那里輸入“!analyze -v”,WinDbg會自動根據(jù)信息分析出崩潰的代碼行數(shù),部分結果如下:
任務達成!
五、注意事項
六、分析
1、若源碼位置改動,我這里把路徑下的工程名改為“ErrorDLL00”,WinDbg的部分分析結果如下:
WRITE_ADDRESS: 00000008 FOLLOWUP_IP: ErrorDLL!XError::ErrorFun+6 [d:\errordll\errordll\xerror.cpp @ 16] 70591036 c740080a000000 mov dword ptr [eax+8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 00001dacBUGCHECK_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 01201054 to 70591036STACK_TEXT: 0038fab8 01201054 00000000 4546f4ea 01203018 ErrorDLL!XError::ErrorFun+0x6 [d:\errordll\errordll\xerror.cpp @ 16] WARNING: Stack unwind information not available. Following frames may be wrong. 0038fae0 01201268 00000001 00601ba8 00604150 TEST1+0x1054 0038fb24 74a2336a 7efde000 0038fb70 77039902 TEST1+0x1268 0038fb30 77039902 7efde000 7733d33e 00000000 kernel32!BaseThreadInitThunk+0x12 0038fb70 770398d5 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x63 0038fb88 00000000 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbFAULTING_SOURCE_CODE: No source found for 'd:\errordll\errordll\xerror.cpp'SYMBOL_STACK_INDEX: 0SYMBOL_NAME: errordll!XError::ErrorFun+6FOLLOWUP_NAME: MachineOwnerIMAGE_NAME: ErrorDLL.dllBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_ErrorDLL.dll!XError::ErrorFunWATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/TEST1_exe/0_0_0_0/5a5c1877/ErrorDLL_dll/0_0_0_0/5a5d4b1a/c0000005/00001036.htm?Retriage=1大家可以發(fā)現(xiàn),雖然WinDbg仍然可以分析出源碼異常行號,但是不能再顯示出對應的源碼。
在源碼對應位置顯示的內(nèi)容如下:
大家可以發(fā)現(xiàn),WinDbg不能在該路徑下發(fā)現(xiàn)源碼文件,故無法顯示對應的異常源碼。那么這個源碼路徑哪來的呢?之前的文章介紹過,這個源碼路徑就是存儲在ErrorDLL.dll指定的ErrorDLL.pdb中。
2、若源碼位置沒有改動,我將ErrorDLL工程中pdb文件生成目錄下的pdb文件刪除,部分結果如下:
大家可以發(fā)現(xiàn),如果pdb文件不存在的話,WinDbg就無法分析出源碼位置了。
七、總結
八、源碼
http://download.csdn.net/download/itworld123/10207344
總結
以上是生活随笔為你收集整理的VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。