前言
在產品的實際應用環境中,如果我們的程序在客戶那里出現了問題,例如程序異常了,而這個時候的現象又不能還原或者很難還原重現,那么只有使用dump文件來保存程序的當前運行信息,例如調用堆棧等,同時使用符號文件來定位問題了;這里主要講解使用dbghelp庫來生成輸出dump文件,同時使用符號文件和windbg來分析問題。
樣例代碼
1 #include "stdafx.h" 2 #include <Windows.h> 3 #include <iostream> 4 #include "dbghelp.h" 5 using namespace std; 6 LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) 7 { 8 cout << "Enter TopLevelExceptionFilter Function" << endl; 9 HANDLE hFile = CreateFile( _T("project.dmp"),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 10 MINIDUMP_EXCEPTION_INFORMATION stExceptionParam; 11 stExceptionParam.ThreadId = GetCurrentThreadId(); 12 stExceptionParam.ExceptionPointers = pExceptionInfo; 13 stExceptionParam.ClientPointers = FALSE; 14 MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hFile,MiniDumpWithFullMemory,&stExceptionParam,NULL,NULL); 15 CloseHandle(hFile); 16 getchar(); 17 return EXCEPTION_EXECUTE_HANDLER; 18 } 19 20 int _tmain(int argc, _TCHAR* argv[]) 21 { 22 cout<<"Enter Main Function"<<endl; 23 SetUnhandledExceptionFilter(TopLevelExceptionFilter); 24 int *pValue = NULL; 25 cout<<"Invalid Access"<<endl; 26 *pValue = 0; 27 cout<<"Finish Main Function"<<endl; 28 getchar(); 29 30 return 0; 31 }
該段代碼很簡單,有幾個API函數大家查查msdn即可;我就不再講解了.
工程設置
由於使用了dbghelp庫,因此我們需要配置庫依賴以及頭文件包含信息;設置頭文件包含如下圖所示:
設置庫文件依賴如下圖所示:
設置好之后,即可成功編譯該工程代碼,同時將dbghelp.dll文件放入可執行文件目錄下;最后結果如下圖所示:
由於我默認設置了生成符號文件,即DumpProject.pdb文件;關於符號文件的生成,如下圖設置所示:
運行程序
雙擊DumpProject.exe文件,根據代碼邏輯,由於程序有異常,因此會生成dump文件,運行結果如下圖所示:
同時生成了project.dmp文件,如下圖所示:
分析問題
得到了dmp文件,符號文件,同時又有對應的源碼,這時使用WinDbg工具來解決問題,找出異常出在哪里。
打開WinDbg工具,設置好符號文件位置目錄,源碼文件位置目錄,然后打開project.dmp文件,顯示如下所示:
在WinDbg命令行中輸入如下!analyze -v命令,從而可以分析出異常出現的具體位置,如下圖所示:
結束
方便快捷的定位分析問題,提高效率;