首页 > 代码库 > C++生成dump文件

C++生成dump文件

C++代码中,使用DbgHelp模块的MINIDUMP编程生成

#include "DbgHelp.h"typedef BOOL (WINAPI* MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,                                               CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,                                                CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,                                                CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); long CSE_Exception::_DbgDumpError(struct _EXCEPTION_POINTERS *excpInfo, LPCTSTR szPrex ){      LONG retval = EXCEPTION_CONTINUE_SEARCH;      HMODULE hDll = ::LoadLibrary(_T("DBGHELP.DLL"));     LPCTSTR szResult = NULL;     MINIDUMPWRITEDUMP pDump = NULL;      if (hDll)         pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll,"MiniDumpWriteDump");      if (pDump)     {         TCHAR szDumpPath [_MAX_PATH] = {0};         TCHAR szDumpFile [_MAX_PATH] = {0};         GetModuleFileName(NULL, szDumpPath, _MAX_PATH);         _tcsrchr(szDumpPath, _T(‘\\‘))[1] = 0;         _tcscat(szDumpPath, _T("..\\logs\"));          time_t timeCurrent = time(0);         struct tm* tmc = localtime(&timeCurrent);         if ( tmc )              _stprintf(szDumpFile, _T("%s%d_%d_%d_%d_%d.dmp"), szPrex, tmc->tm_mon+1, tmc->tm_mday, tmc->tm_hour, tmc->tm_min, tmc->tm_sec);         else              _tcscpy(szDumpFile, _T("error.dmp"));         _tcscat(szDumpPath, szDumpFile);          // create the file         HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,              FILE_ATTRIBUTE_NORMAL, NULL );          if (hFile!=INVALID_HANDLE_VALUE)         {              if (excpInfo == NULL) //如果没有传入异常, 比如是在程序里面调用的, 生成一个异常              {                   // Generate exception to get proper context in dump                                     DWORD dwSize = 0;                   char *sz = "_EXCEPTION_POINTERS is null";                   ::WriteFile(hFile, sz, strlen(sz), &dwSize, NULL);              }              else              {                   MINIDUMP_EXCEPTION_INFORMATION eInfo;                   eInfo.ThreadId = GetCurrentThreadId(); //把需要的信息添进去                   eInfo.ExceptionPointers = excpInfo;                   eInfo.ClientPointers = FALSE;                    // Dump的类型是小型的, 节省空间. 可以参考MSDN生成更详细的Dump.                   pDump(                       GetCurrentProcess(),                       GetCurrentProcessId(),                       hFile,                       MiniDumpNormal,                       excpInfo ? &eInfo : NULL,                       NULL,                       NULL);              }              ::CloseHandle(hFile);          }     }     if( hDll )         ::FreeLibrary(hDll);      return retval;}  void CSE_Exception::InitSEException(){     _set_se_translator( CSE_Exception::trans_func );} void CSE_Exception::_DumpCallStack(){     __try     {         __try         {              RaiseException(1, 0, 0, NULL);         }         __finally         {         }     }     __except(_DbgDumpError(GetExceptionInformation(), _T("T")),         EXCEPTION_CONTINUE_EXECUTION)     {     }} void CSE_Exception::trans_func( unsigned int uSENum, _EXCEPTION_POINTERS* pExp ){#define SE_BUF_SIZE         250     TCHAR pszBuf[SE_BUF_SIZE+2];      _DbgDumpError(pExp, _T("e"));     switch(uSENum)     {     case EXCEPTION_ACCESS_VIOLATION:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("Access Violation: IP: 0xX %s Address: 0xX"),              pExp->ExceptionRecord->ExceptionAddress, pExp->ExceptionRecord->ExceptionInformation[0]?_T("Write"):_T("Read"), pExp->ExceptionRecord->ExceptionInformation[1]);         break;     case EXCEPTION_INT_DIVIDE_BY_ZERO:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("INT_DIVIDE_BY_ZERO"));         break;     case EXCEPTION_FLT_DIVIDE_BY_ZERO:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("FLT_DIVIDE_BY_ZERO"));         break;     case EXCEPTION_ILLEGAL_INSTRUCTION:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("ILLEGAL_INSTRUCTION"));         break;     case EXCEPTION_PRIV_INSTRUCTION:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("EXCEPTION_PRIV_INSTRUCTION"));         break;     case EXCEPTION_STACK_OVERFLOW:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("EXCEPTION_STACK_OVERFLOW"));         break;     default:         _sntprintf(pszBuf, SE_BUF_SIZE, _T("Unknown SE_exception: X"), uSENum);         break;     }      CSE_Exception e(pszBuf);     e.m_nSENumber = uSENum;     e.m_SERecord  = *(pExp->ExceptionRecord);     e.m_SEContext  = *(pExp->ContextRecord);      throw e;}

  然后在程序的InitInstance中加入代码如下:

LONG WINAPI DbgUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo){     CSE_Exception::_DbgDumpError(pExceptionInfo, _T("E"));     return EXCEPTION_CONTINUE_SEARCH;    // 程序停止运行}BOOL CDCPWorkerApp::InitInstance(){     //EHA     CSE_Exception::InitSEException();     //捕获未处理的异常     SetUnhandledExceptionFilter(DbgUnhandledExceptionFilter);}

  

C++生成dump文件