轉自:http://www.cnblogs.com/sz-leez/p/5942692.html
C++代碼中,使用DbgHelp模塊的MINIDUMP編程生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#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中加入代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
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); }
|