• 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);
    }
    

      

  • 相关阅读:
    Shell中调用java时的参数
    简析echo命令在Linux系统中的使用
    设置Linux环境变量的三种方法
    nohup 后台运行,以及重定向标准输出和标准错误 &/dev/null 文件
    &命令
    linux下卸载gij的java
    在Linux下运行可执行Jar包
    jar参数运行应用时classpath的设置方法
    shell获取当前进程pid和上一个进程pid
    检查文件,如果文件不存在则创建
  • 原文地址:https://www.cnblogs.com/sz-leez/p/5942692.html
Copyright © 2020-2023  润新知