windows下生成core dump文件

http://blog.csdn.net/xiarendeniao/article/details/7306282


下面是从pandion里面摘取的两个文件

MiniDumper.h

[cpp] view plain copy
  1. #ifndef MINIDUMPER_H  
  2. #define MINIDUMPER_H  
  3.   
  4. #include <windows.h>  
  5.   
  6. class CMiniDumper  
  7. {  
  8. public:  
  9.   
  10.     CMiniDumper(bool bPromptUserForMiniDump);  
  11.     ~CMiniDumper(void);  
  12.   
  13. private:  
  14.   
  15.     static LONG WINAPI unhandledExceptionHandler(struct _EXCEPTION_POINTERS *pExceptionInfo);  
  16.     void setMiniDumpFileName(void);  
  17.     bool getImpersonationToken(HANDLE* phToken);  
  18.     BOOL enablePrivilege(LPCTSTR pszPriv, HANDLE hToken, TOKEN_PRIVILEGES* ptpOld);  
  19.     BOOL restorePrivilege(HANDLE hToken, TOKEN_PRIVILEGES* ptpOld);  
  20.     LONG writeMiniDump(_EXCEPTION_POINTERS *pExceptionInfo );  
  21.   
  22.     _EXCEPTION_POINTERS *m_pExceptionInfo;  
  23.     TCHAR m_szMiniDumpPath[MAX_PATH];  
  24.     TCHAR m_szAppPath[MAX_PATH];  
  25.     TCHAR m_szAppBaseName[MAX_PATH];  
  26.     bool m_bPromptUserForMiniDump;  
  27.   
  28.     static CMiniDumper* s_pMiniDumper;  
  29.     static LPCRITICAL_SECTION s_pCriticalSection;  
  30. };  
  31.   
  32. #endif // MINIDUMPER_H  

MiniDumper.cpp

[cpp] view plain copy
  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #include <assert.h>  
  4. #include <time.h>  
  5. #include <stdlib.h>  
  6. #include <strsafe.h>  
  7. //#include <tchar.h>  
  8. #include <dbghelp.h>  
  9. #include "miniDumper.h"  
  10.   
  11. #ifdef UNICODE  
  12.     #define _tcssprintf wsprintf  
  13.     #define tcsplitpath _wsplitpath  
  14. #else  
  15.     #define _tcssprintf sprintf  
  16.     #define tcsplitpath _splitpath  
  17. #endif  
  18.   
  19. const int USER_DATA_BUFFER_SIZE = 4096;  
  20.   
  21. //-----------------------------------------------------------------------------  
  22. // GLOBALS  
  23. //-----------------------------------------------------------------------------  
  24. CMiniDumper* CMiniDumper::s_pMiniDumper = NULL;  
  25. LPCRITICAL_SECTION CMiniDumper::s_pCriticalSection = NULL;  
  26.   
  27. // Based on dbghelp.h  
  28. typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess,  
  29.                                          DWORD dwPid,  
  30.                                          HANDLE hFile,  
  31.                                          MINIDUMP_TYPE DumpType,  
  32.                                          CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,  
  33.                                          CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,  
  34.                                          CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);  
  35.   
  36. //-----------------------------------------------------------------------------  
  37. // Name: CMiniDumper()  
  38. // Desc: Constructor  
  39. //-----------------------------------------------------------------------------  
  40. CMiniDumper::CMiniDumper( bool bPromptUserForMiniDump )  
  41. {  
  42.     // Our CMiniDumper should act alone as a singleton.  
  43.     assert( !s_pMiniDumper );  
  44.   
  45.     s_pMiniDumper = this;  
  46.     m_bPromptUserForMiniDump = bPromptUserForMiniDump;  
  47.   
  48.     // The SetUnhandledExceptionFilter function enables an application to   
  49.     // supersede the top-level exception handler of each thread and process.  
  50.     // After calling this function, if an exception occurs in a process   
  51.     // that is not being debugged, and the exception makes it to the   
  52.     // unhandled exception filter, that filter will call the exception   
  53.     // filter function specified by the lpTopLevelExceptionFilter parameter.  
  54.     ::SetUnhandledExceptionFilter( unhandledExceptionHandler );  
  55.   
  56.     // Since DBGHELP.dll is not inherently thread-safe, making calls into it   
  57.     // from more than one thread simultaneously may yield undefined behavior.   
  58.     // This means that if your application has multiple threads, or is   
  59.     // called by multiple threads in a non-synchronized manner, you need to    
  60.     // make sure that all calls into DBGHELP.dll are isolated via a global  
  61.     // critical section.  
  62.     s_pCriticalSection = new CRITICAL_SECTION;  
  63.   
  64.     if( s_pCriticalSection )  
  65.         InitializeCriticalSection( s_pCriticalSection );  
  66. }  
  67.   
  68. //-----------------------------------------------------------------------------  
  69. // Name: ~CMiniDumper()  
  70. // Desc: Destructor  
  71. //-----------------------------------------------------------------------------  
  72. CMiniDumper::~CMiniDumper( void )  
  73. {  
  74.     if( s_pCriticalSection )  
  75.     {  
  76.         DeleteCriticalSection( s_pCriticalSection );  
  77.         delete s_pCriticalSection;  
  78.     }  
  79. }  
  80.   
  81. //-----------------------------------------------------------------------------  
  82. // Name: unhandledExceptionHandler()  
  83. // Desc: Call-back filter function for unhandled exceptions  
  84. //-----------------------------------------------------------------------------  
  85. LONG CMiniDumper::unhandledExceptionHandler( _EXCEPTION_POINTERS *pExceptionInfo )  
  86. {  
  87.     if( !s_pMiniDumper )  
  88.         return EXCEPTION_CONTINUE_SEARCH;  
  89.   
  90.     return s_pMiniDumper->writeMiniDump( pExceptionInfo );  
  91. }  
  92.   
  93. //-----------------------------------------------------------------------------  
  94. // Name: setMiniDumpFileName()  
  95. // Desc:   
  96. //-----------------------------------------------------------------------------  
  97. void CMiniDumper::setMiniDumpFileName( void )  
  98. {  
  99.     time_t currentTime;  
  100.     time( ¤tTime );  
  101.   
  102.     wsprintf( m_szMiniDumpPath,  
  103.                  L"%s%s.%ld.dmp",  
  104.                  m_szAppPath,  
  105.                  m_szAppBaseName,  
  106.                  currentTime );  
  107. }  
  108.   
  109. //-----------------------------------------------------------------------------  
  110. // Name: getImpersonationToken()  
  111. // Desc: The method acts as a potential workaround for the fact that the   
  112. //       current thread may not have a token assigned to it, and if not, the   
  113. //       process token is received.  
  114. //-----------------------------------------------------------------------------  
  115. bool CMiniDumper::getImpersonationToken( HANDLE* phToken )  
  116. {  
  117.     *phToken = NULL;  
  118.   
  119.     if( !OpenThreadToken( GetCurrentThread(),  
  120.                           TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,  
  121.                           TRUE,  
  122.                           phToken) )  
  123.     {  
  124.         if( GetLastError() == ERROR_NO_TOKEN )  
  125.         {  
  126.             // No impersonation token for the current thread is available.   
  127.             // Let's go for the process token instead.  
  128.             if( !OpenProcessToken( GetCurrentProcess(),  
  129.                                    TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,  
  130.                                    phToken) )  
  131.                 return false;  
  132.         }  
  133.         else  
  134.             return false;  
  135.     }  
  136.   
  137.     return true;  
  138. }  
  139.   
  140. //-----------------------------------------------------------------------------  
  141. // Name: enablePrivilege()  
  142. // Desc: Since a MiniDump contains a lot of meta-data about the OS and   
  143. //       application state at the time of the dump, it is a rather privileged   
  144. //       operation. This means we need to set the SeDebugPrivilege to be able   
  145. //       to call MiniDumpWriteDump.  
  146. //-----------------------------------------------------------------------------  
  147. BOOL CMiniDumper::enablePrivilege( LPCTSTR pszPriv, HANDLE hToken, TOKEN_PRIVILEGES* ptpOld )  
  148. {  
  149.     BOOL bOk = FALSE;  
  150.   
  151.     TOKEN_PRIVILEGES tp;  
  152.     tp.PrivilegeCount = 1;  
  153.     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
  154.     bOk = LookupPrivilegeValue( 0, pszPriv, &tp.Privileges[0].Luid );  
  155.   
  156.     if( bOk )  
  157.     {  
  158.         DWORD cbOld = sizeof(*ptpOld);  
  159.         bOk = AdjustTokenPrivileges( hToken, FALSE, &tp, cbOld, ptpOld, &cbOld );  
  160.     }  
  161.   
  162.     return (bOk && (ERROR_NOT_ALL_ASSIGNED != GetLastError()));  
  163. }  
  164.   
  165. //-----------------------------------------------------------------------------  
  166. // Name: restorePrivilege()  
  167. // Desc:   
  168. //-----------------------------------------------------------------------------  
  169. BOOL CMiniDumper::restorePrivilege( HANDLE hToken, TOKEN_PRIVILEGES* ptpOld )  
  170. {  
  171.     BOOL bOk = AdjustTokenPrivileges(hToken, FALSE, ptpOld, 0, NULL, NULL);  
  172.     return ( bOk && (ERROR_NOT_ALL_ASSIGNED != GetLastError()) );  
  173. }  
  174.   
  175. //-----------------------------------------------------------------------------  
  176. // Name: writeMiniDump()  
  177. // Desc:   
  178. //-----------------------------------------------------------------------------  
  179. LONG CMiniDumper::writeMiniDump( _EXCEPTION_POINTERS *pExceptionInfo )  
  180. {  
  181.     LONG retval = EXCEPTION_CONTINUE_SEARCH;  
  182.     m_pExceptionInfo = pExceptionInfo;  
  183.   
  184.     HANDLE hImpersonationToken = NULL;  
  185.     if( !getImpersonationToken( &hImpersonationToken ) )  
  186.         return FALSE;  
  187.   
  188.     // You have to find the right dbghelp.dll.   
  189.     // Look next to the EXE first since the one in System32 might be old (Win2k)  
  190.       
  191.     HMODULE hDll = NULL;  
  192.     TCHAR szDbgHelpPath[MAX_PATH];  
  193.   
  194.     if( GetModuleFileName( NULL, m_szAppPath, _MAX_PATH ) )  
  195.     {  
  196.         TCHAR *pSlash = wcsrchr( m_szAppPath, '\\' );  
  197.   
  198.         if( pSlash )  
  199.         {  
  200.             _tcscpy( m_szAppBaseName, pSlash + 1);  
  201.             *(pSlash+1) = 0;  
  202.         }  
  203.   
  204.         wcscpy( szDbgHelpPath, m_szAppPath );  
  205.         wcscat( szDbgHelpPath, L"DBGHELP.DLL");  
  206.         hDll = ::LoadLibrary( szDbgHelpPath );  
  207.     }  
  208.   
  209.     if( hDll == NULL )  
  210.     {  
  211.         // If we haven't found it yet - try one more time.  
  212.         hDll = ::LoadLibrary( L"DBGHELP.DLL");  
  213.     }  
  214.   
  215.     LPCTSTR szResult = NULL;  
  216.   
  217.     if( hDll )  
  218.     {  
  219.         // Get the address of the MiniDumpWriteDump function, which writes   
  220.         // user-mode mini-dump information to a specified file.  
  221.         MINIDUMPWRITEDUMP MiniDumpWriteDump =   
  222.             (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" );  
  223.   
  224.         if( MiniDumpWriteDump != NULL )  
  225.         {  
  226.             TCHAR szScratch[USER_DATA_BUFFER_SIZE];  
  227.   
  228.             setMiniDumpFileName();  
  229.   
  230.             // Ask the user if he or she wants to save a mini-dump file...  
  231.             wsprintf( szScratch,  
  232.                          L"There was an unexpected error:\n\nWould you "  
  233.                          L"like to create a mini-dump file?\n\n%s ",  
  234.                          m_szMiniDumpPath);  
  235.   
  236.             // Create the mini-dump file...  
  237.             HANDLE hFile = ::CreateFile( m_szMiniDumpPath,   
  238.                                             GENERIC_WRITE,   
  239.                                             FILE_SHARE_WRITE,   
  240.                                             NULL,   
  241.                                             CREATE_ALWAYS,   
  242.                                             FILE_ATTRIBUTE_NORMAL,   
  243.                                             NULL );  
  244.   
  245.             if( hFile != INVALID_HANDLE_VALUE )  
  246.             {  
  247.                 _MINIDUMP_EXCEPTION_INFORMATION ExInfo;  
  248.                 ExInfo.ThreadId          = ::GetCurrentThreadId();  
  249.                 ExInfo.ExceptionPointers = pExceptionInfo;  
  250.                 ExInfo.ClientPointers    = NULL;  
  251.   
  252.                 // We need the SeDebugPrivilege to be able to run MiniDumpWriteDump  
  253.                 TOKEN_PRIVILEGES tp;  
  254.                 BOOL bPrivilegeEnabled = enablePrivilege( SE_DEBUG_NAME, hImpersonationToken, &tp );  
  255.   
  256.                 BOOL bOk;  
  257.   
  258.                 // DBGHELP.dll is not thread-safe, so we need to restrict access...  
  259.                 EnterCriticalSection( s_pCriticalSection );  
  260.                 {  
  261.                     // Write out the mini-dump data to the file...  
  262.                     bOk = MiniDumpWriteDump( GetCurrentProcess(),  
  263.                                                 GetCurrentProcessId(),  
  264.                                                 hFile,  
  265.                                                 MiniDumpNormal,  
  266.                                                 &ExInfo,  
  267.                                                 NULL,  
  268.                                                 NULL );  
  269.                 }  
  270.                 LeaveCriticalSection( s_pCriticalSection );  
  271.   
  272.                 // Restore the privileges when done  
  273.                 if( bPrivilegeEnabled )  
  274.                     restorePrivilege( hImpersonationToken, &tp );  
  275.   
  276.                 if( bOk )  
  277.                 {  
  278.                     szResult = NULL;  
  279.                     retval = EXCEPTION_EXECUTE_HANDLER;  
  280.                 }  
  281.                 else  
  282.                 {  
  283.                     wsprintf( szScratch,  
  284.                                     L"Failed to save the mini-dump file to '%s' (error %d)",  
  285.                                     m_szMiniDumpPath,  
  286.                                     GetLastError() );  
  287.   
  288.                     szResult = szScratch;  
  289.                 }  
  290.   
  291.                 ::CloseHandle( hFile );  
  292.             }  
  293.             else  
  294.             {  
  295.                 wsprintf( szScratch,  
  296.                                 L"Failed to create the mini-dump file '%s' (error %d)",  
  297.                                 m_szMiniDumpPath,  
  298.                                 GetLastError() );  
  299.   
  300.                 szResult = szScratch;  
  301.             }  
  302.         }  
  303.         else  
  304.         {  
  305.             szResult = L"Call to GetProcAddress failed to find MiniDumpWriteDump. "  
  306.                        L"The DBGHELP.DLL is possibly outdated." ;  
  307.         }  
  308.     }  
  309.     else  
  310.     {  
  311.         szResult = L"Call to LoadLibrary failed to find DBGHELP.DLL.";  
  312.     }  
  313.   
  314.     if( szResult && m_bPromptUserForMiniDump )  
  315.         ::MessageBox( NULL, szResult, NULL, MB_OK );  
  316.   
  317.     TerminateProcess( GetCurrentProcess(), 0 );  
  318.   
  319.     return retval;  
  320. }  


要在项目中使用,只需在入口文件加上下面代码即可

[cpp] view plain copy
  1. #include "MiniDumper.h"  
  2.   
  3. CMiniDumper g_miniDumper( true );  

展开阅读全文

没有更多推荐了,返回首页