-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExceptionErrorHandler.h
321 lines (266 loc) · 11.5 KB
/
ExceptionErrorHandler.h
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/*
************************************************************************************
*
* File: ExceptionErrorHandler.h
* Class: CExceptErrorHandler
*
************************************************************************************
* Description:
*
************************************************************************************
* Notes:
*
* 20/12/2008
*
************************************************************************************
*
* E/Mail: ian.macallan@gmail.com
* (c) 2003 - 2023 / Macallan
*
************************************************************************************
*
*
* Matt Pietrek
* MSDN Magazine, 2002
*
* Litely adapted by Macallan.
* FILE: MacallanExceptionHandler.h
*
************************************************************************************
*/
#pragma once
#ifdef EXCEPTION_ERROR_HANDLER
#include <dbghelp.h>
//=============================================================================
//
//
//
//=============================================================================
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
//
//====================================================================================
//
// Global Function Pointers
//
//====================================================================================
typedef BOOL ( __stdcall * typeSymGetTypeInfo )(
IN HANDLE hProcess,
IN DWORD64 ModBase,
IN ULONG TypeId,
IN IMAGEHLP_SYMBOL_TYPE_INFO GetType,
OUT PVOID pInfo
);
typedef DWORD ( __stdcall * typeSymSetOptions ) (
IN DWORD SymOptions
);
typedef DWORD ( __stdcall * typeSymGetOptions ) ( );
typedef BOOL ( __stdcall * typeSymInitialize ) (
IN HANDLE hProcess,
IN PCSTR UserSearchPath,
IN BOOL fInvadeProcess
);
typedef BOOL ( __stdcall * typeSymCleanup ) (
IN HANDLE hProcess
);
typedef BOOL ( __stdcall * typeSymEnumSymbols ) (
IN HANDLE hProcess,
IN ULONG64 BaseOfDll,
IN PCSTR Mask,
IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
IN PVOID UserContext
);
typedef BOOL ( __stdcall * typeSymSetContext ) (
HANDLE hProcess,
PIMAGEHLP_STACK_FRAME StackFrame,
PIMAGEHLP_CONTEXT Context
);
typedef BOOL ( __stdcall * typeSymFromAddr )(
IN HANDLE hProcess,
IN DWORD64 Address,
OUT PDWORD64 Displacement,
IN OUT PSYMBOL_INFO Symbol
);
typedef BOOL ( __stdcall * typeSymGetLineFromAddr )(
IN HANDLE hProcess,
IN DWORD dwAddr,
OUT PDWORD pdwDisplacement,
OUT PIMAGEHLP_LINE Line
);
typedef BOOL ( __stdcall * typeSymGetLineFromAddr64 )(
IN HANDLE hProcess,
IN DWORD64 dwAddr,
OUT PDWORD pdwDisplacement,
OUT PIMAGEHLP_LINE64 Line
);
typedef BOOL ( __stdcall * typeStackWalk )(
DWORD MachineType,
HANDLE hProcess,
HANDLE hThread,
LPSTACKFRAME StackFrame,
PVOID ContextRecord,
PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
);
typedef BOOL ( __stdcall * typeStackWalk64 )(
DWORD MachineType,
HANDLE hProcess,
HANDLE hThread,
LPSTACKFRAME64 StackFrame,
PVOID ContextRecord,
PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
);
typedef PVOID ( __stdcall * typeSymFunctionTableAccess )(
HANDLE hProcess,
DWORD AddrBase
);
typedef PVOID ( __stdcall * typeSymFunctionTableAccess64 )(
HANDLE hProcess,
DWORD64 AddrBase
);
typedef DWORD ( __stdcall * typeSymGetModuleBase )(
IN HANDLE hProcess,
IN DWORD dwAddr
);
typedef DWORD64 ( __stdcall * typeSymGetModuleBase64 )(
IN HANDLE hProcess,
IN DWORD64 dwAddr
);
typedef USHORT ( __stdcall * typeRtlCaptureStackBackTrace )(
IN ULONG FramesToSkip,
IN ULONG FramesToCapture,
PVOID *BackTrace,
PULONG BackTraceHash
);
//
//=============================================================================
//
// The Macallan Exception Handler.
//
//=============================================================================
//! MacallanExceptionHandler
class CExceptErrorHandler
{
public:
CExceptErrorHandler ( );
virtual ~CExceptErrorHandler( );
static void EEHSetLogFileName( char *pszLogFileName, size_t cbSize );
static char * EEHGetFilename(char * pName);
static void EEHGetDirectory(char * pName, size_t iSize);
static void EEHGetTempDirectory(char * pName, size_t iSize);
// entry point where control comes on an unhandled exception
static LONG WINAPI EEHMacallanUnhandledExceptionFilter( PEXCEPTION_POINTERS pExceptionInfo );
static void EEHInvalidParameterHandler ( const wchar_t * expression, const wchar_t * function,
const wchar_t * file, unsigned int line, uintptr_t pReserved );
private:
// where report info is extracted and generated
static void EEHGenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo );
// Helper functions
static char * EEHGetExceptionString ( DWORD dwCode );
static BOOL EEHGetLogicalAddress ( PVOID addr, char * szModule, DWORD len,
DWORD& section, DWORD& offset );
static void EEHWriteStackDetails( PCONTEXT pContext, bool bWriteVariables );
static BOOL CALLBACK EEHEnumerateSymbolsCallback ( PSYMBOL_INFO, ULONG, PVOID );
static bool EEHFormatSymbolValue( PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer );
static char * EEHDumpTypeIndex ( char *, size_t, DWORD64, DWORD, unsigned, DWORD_PTR, bool & );
static char * EEHFormatOutputValue ( char * pszCurrBuffer, size_t cbCurrBuffer,
BasicType basicType, DWORD64 length,
PVOID pAddress );
static BasicType EEHGetBasicType ( DWORD typeIndex, DWORD64 modBase );
static BOOL EEHEnableCrashingOnCrashes ();
static size_t __cdecl EEHPrintCrash ( const char * format, ... );
static size_t __cdecl EEHPrintDebug ( const char * format, ... );
static void EEHWriteStackTrace ();
static const char *EEHGetLastErrorText ( );
static void EEHInitializeSymbols();
static void EEHSetInvalidParameterHandler ();
static void EEHOpenDebugFile();
static void EEHCloseDebugFile();
static void EEHOpenCrashFile();
static void EEHCloseCrashFile();
//
// External functions
static typeSymInitialize pfSymInitialize;
static typeSymGetTypeInfo pfSymGetTypeInfo;
static typeSymSetOptions pfSymSetOptions;
static typeSymGetOptions pfSymGetOptions;
static typeSymCleanup pfSymCleanup;
static typeSymEnumSymbols pfSymEnumSymbols;
static typeSymSetContext pfSymSetContext;
static typeSymFromAddr pfSymFromAddr;
static typeSymGetLineFromAddr pfSymGetLineFromAddr;
static typeSymGetLineFromAddr64 pfSymGetLineFromAddr64;
static typeStackWalk pfStackWalk;
static typeStackWalk64 pfStackWalk64;
static typeSymFunctionTableAccess pfSymFunctionTableAccess;
static typeSymFunctionTableAccess64 pfSymFunctionTableAccess64;
static typeSymGetModuleBase pfSymGetModuleBase;
static typeSymGetModuleBase64 pfSymGetModuleBase64;
static typeRtlCaptureStackBackTrace pfRtlCaptureStackBackTrace;
// Variables used by the class
static char m_szDebugFileName[MAX_PATH+1];
static char m_szCrashFileName[MAX_PATH+1];
static char m_szDirectory[MAX_PATH+1];
static char m_szSearchPath[MAX_PATH+1];
static char m_szFilename[MAX_PATH+1];
static char m_szModule[MAX_PATH+1];
static char m_szFaultingModule[MAX_PATH+1];
static char m_szBuffer[MAX_PATH*4+1];
static WCHAR m_szwBuffer[MAX_PATH*4+1];
static char m_szSymbolBuffer[MAX_PATH*8+1];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static HANDLE m_hCrashFile;
static HANDLE m_hDebugFile;
static HANDLE m_hProcess;
static char m_szErrorText[MAX_PATH*2+1];
#define SYMBOL_NAME_LEN 256
static char m_SymbolInfo [ sizeof(SYMBOL_INFO) + SYMBOL_NAME_LEN * sizeof( char )];
static SYMBOL_INFO *m_pSymbolInfo;
static _invalid_parameter_handler m__invalid_parameter_handler;
};
#endif // EXCEPTION_ERROR_HANDLER
//
// External Functions
extern void InvokeExceptionErrorHandler( );
extern void SetCrashToStderr( bool toStdErr );
extern BOOL TreatCrashOptionsW(int iArgCount, WCHAR* pArgValues[], const WCHAR* pOption, int &iX);
extern BOOL TreatCrashOptionsA(int iArgCount, char* pArgValues[], const char* pOption, int &iX);
extern void PrintCrashHelpW ( int iWidth, const WCHAR *programName, int iArgCount, WCHAR* pArgValues[], bool bLong, bool bTwo = false );
extern void PrintCrashHelpA ( int iWidth, const char *programName, int iArgCount, char* pArgValues[], bool bLong, bool bTwo = false );
//
extern bool InvalidParameterFound;
extern _invalid_parameter_handler SetInvalidParameterHandler ( _invalid_parameter_handler newInvalidParameterHandler = NULL );
extern void RestoreInvalidParameterHandler ( _invalid_parameter_handler oldInvalidParameterHandler = NULL );
extern _invalid_parameter_handler OldInvalidParameterHandler;
//
#ifdef UNICODE
#define TreatCrashOptions TreatCrashOptionsW
#define PrintCrashHelp PrintCrashHelpW
#else
#define TreatCrashOptions TreatCrashOptionsA
#define PrintCrashHelp PrintCrashHelpA
#endif