1. 程式人生 > >使用dbghelp生成dump檔案以及事後除錯分析

使用dbghelp生成dump檔案以及事後除錯分析

前言

在產品的實際應用環境中,如果我們的程式在客戶那裡出現了問題,例如程式異常了,而這個時候的現象又不能還原或者很難還原重現,那麼只有使用dump檔案來儲存程式的當前執行資訊,例如呼叫堆疊等,同時使用符號檔案來定位問題了;這裡主要講解使用dbghelp庫來生成輸出dump檔案,同時使用符號檔案和windbg來分析問題。

這個dbghelp.dll是系統庫,一般不用放到產品目錄中。但是阿里釘釘,愛奇藝PPS都在安裝目錄下帶上了這個庫,可能是要用最新版本的dbghelp.dll庫,也可能防止系統中的庫被刪除掉,導致無法匯出dump檔案。


樣例程式碼

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include "dbghelp.h"
using namespace std;
LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo)  
{
    cout << "Enter TopLevelExceptionFilter Function" << endl;  
    HANDLE hFile = CreateFile(  _T("project.dmp"),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  
    MINIDUMP_EXCEPTION_INFORMATION stExceptionParam;  
    stExceptionParam.ThreadId    = GetCurrentThreadId();  
    stExceptionParam.ExceptionPointers = pExceptionInfo;  
    stExceptionParam.ClientPointers    = FALSE;  
    MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hFile,MiniDumpWithFullMemory,&stExceptionParam,NULL,NULL);  
    CloseHandle(hFile);  
    getchar();
    return EXCEPTION_EXECUTE_HANDLER;
}

int _tmain(int argc, _TCHAR* argv[])
{
    cout<<"Enter Main Function"<<endl;
    SetUnhandledExceptionFilter(TopLevelExceptionFilter); 
    int *pValue = NULL;
    cout<<"Invalid Access"<<endl;
    *pValue = 0;
    cout<<"Finish Main Function"<<endl;
    getchar();

    return 0;
}
該段程式碼很簡單,有幾個API函式大家查查msdn即可,我就不再講解了。

工程設定

由於使用了dbghelp庫,因此我們需要配置庫依賴以及標頭檔案包含資訊,設定標頭檔案包含如下圖所示:


設定庫檔案依賴如下圖所示:



設定好之後,即可成功編譯該工程程式碼,同時將dbghelp.dll檔案放入可執行檔案目錄下,最後結果如下圖所示:


由於我預設設定了生成符號檔案,即DumpProject.pdb檔案,關於符號檔案的生成,如下圖設定所示:



執行程式

雙擊DumpProject.exe檔案,根據程式碼邏輯,由於程式有異常,因此會生成dump檔案,執行結果如下圖所示:


同時生成了project.dmp檔案,如下圖所示:


分析問題

得到了dmp檔案,符號檔案,同時又有對應的原始碼,這時使用WinDbg工具來解決問題,找出異常出在哪裡。

開啟WinDbg工具,設定好符號檔案位置目錄,原始碼檔案位置目錄,然後開啟project.dmp檔案,顯示如下所示:


在WinDbg命令列中輸入如下!analyze -v命令,從而可以分析出異常出現的具體位置,如下圖所示:



結束

方便快捷的定位分析問題,提高效率。