dump文件生成與調試(VS2008)


  總結一下dump文件生成和調試的方法:  

  1:用SetUnhandledExceptionFilter捕獲未處理的異常,包含頭文件<windows.h>。函數原型為:

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
    __in  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);

  SetUnhandledExceptionFilter返回值為:The SetUnhandledExceptionFilter function returns the address of the previous exception filter established with the function. A NULL return value means that there is no current top-level exception handler.返回回掉函數的地址。

  回掉函數原型為:

1 typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
2     __in struct _EXCEPTION_POINTERS *ExceptionInfo
3     );
4 typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;

  回掉函數須返回以下3種類型:

Value Meaning

EXCEPTION_EXECUTE_HANDLER
0x1

Return from UnhandledExceptionFilter and execute the associated exception handler. This usually results in process termination.捕獲到異常,並在異常處結束程序

EXCEPTION_CONTINUE_EXECUTION
0xffffffff

Return from UnhandledExceptionFilter and continue execution from the point of the exception. Note that the filter function is free to modify the continuation state by modifying the exception information supplied through its LPEXCEPTION_POINTERS parameter.表示錯誤已經被修復,從異常發生處繼續執行。如果在回掉函數內部不對異常進行處理,每次回掉結束又會捕獲到異常,將導致無限進入SetUnhandledExceptionFilter函數,死循環。

EXCEPTION_CONTINUE_SEARCH
0x0

Proceed with normal execution of UnhandledExceptionFilter. That means obeying the SetErrorMode flags, or invoking the Application Error pop-up message box.捕獲到異常,並調用系統默認異常錯誤框,結束程序。

 

  2:在SetUnhandledExceptionFilter的回掉函數中,用MiniDumpWriteDump函數將異常寫入dump文件。需要包含DbgHelp.h,引入#pragma comment(lib, "dbghelp.lib")。MiniDumpWriteDump函數的原型為:

1 BOOL WINAPI MiniDumpWriteDump(
2   __in          HANDLE hProcess,                       //  進程句柄,可以用GetCurrentProcess()獲得
3   __in          DWORD ProcessId,                       //  進程ID,可以用GetCurrentProcessId()獲得
4   __in          HANDLE hFile,                         //   待寫入的dmp文件
5   __in          MINIDUMP_TYPE DumpType,                   //  寫入的dump信息類型,從MINIDUMP_TYPR中選擇。
6   __in          PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,     //  指向異常信息結構的指針,如果該值是NULL,將不會寫入任何異常信息  
7   __in          PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,   //   指向用戶自定義信息塊,可以為NULL
8   __in          PMINIDUMP_CALLBACK_INFORMATION CallbackParam      //   指向回掉函數的擴展信息塊,可以為NULL
9 );

  在MiniDumpWriteDump參數項中,比較重要的是異常信息塊PMINIDUMP_EXCEPTION_INFORMATION,其結構如下:

1 typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
2     DWORD ThreadId;                 //線程ID,可以用GetCurrentThreadId()獲得
3     PEXCEPTION_POINTERS ExceptionPointers;   //指向異常信息指針,EXCEPTION_POINTER內包含了異常信息代碼/flag等內容,異常發生時各寄存器狀態和內容。用回掉函數的參數賦值即可 4     BOOL ClientPointers;              //TRUE和FALSE好像都可以,搞不清楚區別
5 } MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;

  3:了解上述內容后,封裝成類,方便移植。h文件:

 1 #pragma once
 2 #include <string>
 3 using namespace std;
 4 class CCreateDump
 5 {
 6 public:
 7     CCreateDump();
 8     ~CCreateDump(void);
 9     static CCreateDump* Instance();
10     static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo);
11     //聲明Dump文件,異常時會自動生成。會自動加入.dmp文件名后綴
12     void DeclarDumpFile(std::string dmpFileName = "");
13 private:
14     static std::string    strDumpFile; 
15     static CCreateDump*    __instance;
16 };

  cpp文件:

 1 #include "StdAfx.h"
 2 #include "CreateDump.h"
 3 #include <DbgHelp.h>
 4 #pragma comment(lib,  "dbghelp.lib")
 5 
 6 CCreateDump* CCreateDump::__instance = NULL;
 7 std::string CCreateDump::strDumpFile = "";
 8 
 9 CCreateDump::CCreateDump()
10 {
11 }
12 
13 CCreateDump::~CCreateDump(void)
14 {
15     
16 }
17 
18 long  CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo)
19 {
20     HANDLE hFile   =   CreateFile(strDumpFile.c_str(),   GENERIC_WRITE,   FILE_SHARE_WRITE,   NULL,   CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,   NULL   );
21     if(hFile!=INVALID_HANDLE_VALUE)
22     {
23         MINIDUMP_EXCEPTION_INFORMATION   ExInfo; 
24         ExInfo.ThreadId   =   ::GetCurrentThreadId();
25         ExInfo.ExceptionPointers   =   ExceptionInfo;
26         ExInfo.ClientPointers   =   FALSE;
27         //   write   the   dump
28         BOOL   bOK   =   MiniDumpWriteDump(GetCurrentProcess(),   GetCurrentProcessId(),   hFile,   MiniDumpNormal,  &ExInfo,   NULL,   NULL   );
29         CloseHandle(hFile);
30         if (!bOK)
31         {
32             DWORD dw = GetLastError();
33             //寫dump文件出錯處理,異常交給windows處理
34             return EXCEPTION_CONTINUE_SEARCH;
35         }
36         else
37         {    //在異常處結束
38             return EXCEPTION_EXECUTE_HANDLER;
39         }
40     }
42     else
43     {
44         return EXCEPTION_CONTINUE_SEARCH;
45     }
46 }
47 
48 void CCreateDump::DeclarDumpFile(std::string dmpFileName)
49 {
50     SYSTEMTIME syt;
51     GetLocalTime(&syt);
52     char c[MAX_PATH];
53     sprintf_s(c,MAX_PATH,"[%04d-%02d-%02d %02d:%02d:%02d]",syt.wYear,syt.wMonth,syt.wDay,syt.wHour,syt.wMinute,syt.wSecond);
54     strDumpFile = std::string(c);
55     if (!dmpFileName.empty())
56     {
57         strDumpFile += dmpFileName;
58     }
59     strDumpFile += std::string(".dmp");
60     SetUnhandledExceptionFilter(UnhandleExceptionFilter);
61 }
62 
63 CCreateDump* CCreateDump::Instance()
64 {
65     if (__instance == NULL)
66     {
67         __instance = new CCreateDump;
68     }
69     return __instance;
70 }

  調用方法:加入頭文件引用,在程序開始時寫入

CCreateDump::Instance()->DeclarDumpFile("dumpfile");

  4:工程屬性設置,VS2008工程屬性->linker->debugging->Generate Debug Info選擇yes,生成pdb文件。

  5:用vs2008打開dump文件,debug即可。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM