27 #include "precompiled.h"
37 #if MSC_VERSION >= 1400
39 # define NEED_COOKIE_INIT
53 const std::type_info*
ti;
80 if(er->ExceptionCode !=
FOURCC_BE(0xe0,
'm',
's',
'c'))
84 if(er->NumberParameters != 3)
88 if(er->ExceptionInformation[0] != 0x19930520)
103 wchar_t* description,
size_t maxChars)
106 const ULONG_PTR*
const ei = er->ExceptionInformation;
112 char type_buf[100] = {
'\0'};
113 const char* type_name = type_buf;
119 const std::type_info* ti = xti->
ti;
123 if(!strncmp(type_buf,
"class ", 6))
126 __except(EXCEPTION_EXECUTE_HANDLER)
131 char what[160] = {
'\0'};
134 std::exception* e = (std::exception*)ei[1];
137 __except(EXCEPTION_EXECUTE_HANDLER)
144 swprintf_s(description, maxChars, L
"%hs(\"%hs\")", type_name, what);
150 wchar_t* description,
size_t maxChars)
152 const DWORD code = er->ExceptionCode;
153 const ULONG_PTR* ei = er->ExceptionInformation;
162 case EXCEPTION_ACCESS_VIOLATION:
165 const wchar_t* accessType = (ei[0])? L
"writing" : L
"reading";
166 const ULONG_PTR address = ei[1];
167 swprintf_s(description, maxChars, L
"Access violation %ls 0x%08X", accessType, address);
170 case EXCEPTION_DATATYPE_MISALIGNMENT:
return L
"Datatype misalignment";
171 case EXCEPTION_BREAKPOINT:
return L
"Breakpoint";
172 case EXCEPTION_SINGLE_STEP:
return L
"Single step";
173 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
return L
"Array bounds exceeded";
174 case EXCEPTION_FLT_DENORMAL_OPERAND:
return L
"FPU denormal operand";
175 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
return L
"FPU divide by zero";
176 case EXCEPTION_FLT_INEXACT_RESULT:
return L
"FPU inexact result";
177 case EXCEPTION_FLT_INVALID_OPERATION:
return L
"FPU invalid operation";
178 case EXCEPTION_FLT_OVERFLOW:
return L
"FPU overflow";
179 case EXCEPTION_FLT_STACK_CHECK:
return L
"FPU stack check";
180 case EXCEPTION_FLT_UNDERFLOW:
return L
"FPU underflow";
181 case EXCEPTION_INT_DIVIDE_BY_ZERO:
return L
"Integer divide by zero";
182 case EXCEPTION_INT_OVERFLOW:
return L
"Integer overflow";
183 case EXCEPTION_PRIV_INSTRUCTION:
return L
"Privileged instruction";
184 case EXCEPTION_IN_PAGE_ERROR:
return L
"In page error";
185 case EXCEPTION_ILLEGAL_INSTRUCTION:
return L
"Illegal instruction";
186 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
return L
"Noncontinuable exception";
187 case EXCEPTION_STACK_OVERFLOW:
return L
"Stack overflow";
188 case EXCEPTION_INVALID_DISPOSITION:
return L
"Invalid disposition";
189 case EXCEPTION_GUARD_PAGE:
return L
"Guard page";
190 case EXCEPTION_INVALID_HANDLE:
return L
"Invalid handle";
196 swprintf_s(description, maxChars, L
"Unknown (0x%08X)", code);
205 wchar_t* description,
size_t maxChars)
207 const EXCEPTION_RECORD*
const er = ep->ExceptionRecord;
219 wchar_t* file,
int* line,
wchar_t* func)
225 const wchar_t*
const lastFuncToSkip = L
"RaiseException";
243 if(ep->ExceptionRecord->ExceptionCode == 0x40010006)
244 return EXCEPTION_CONTINUE_EXECUTION;
248 if(IsDebuggerPresent())
249 return EXCEPTION_CONTINUE_SEARCH;
254 static intptr_t nestingLevel = 0;
256 if(nestingLevel >= 3)
257 return EXCEPTION_CONTINUE_SEARCH;
271 wchar_t descriptionBuf[150];
278 wchar_t message[500];
279 const wchar_t* messageFormat =
280 L
"Much to our regret we must report the program has encountered an error.\r\n"
282 L
"Please let us know at http://trac.wildfiregames.com/ and attach the crashlog.txt and crashlog.dmp files.\r\n"
284 L
"Details: unhandled exception (%ls)\r\n";
288 if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
296 return EXCEPTION_CONTINUE_SEARCH;
354 #ifdef LIB_STATIC_LINK
361 #define MAIN_STARTUP mainCRTStartup
364 #define MAIN_STARTUP wmainCRTStartup
369 int wmain(
int argc,
wchar_t* argv[])
373 std::vector<char*> utf8_argv(argc);
374 for(
int i = 0; i < argc; i++)
377 utf8_argv[i] = strdup(utf8.c_str());
380 const int ret =
main(argc, &utf8_argv[0]);
382 for(
int i = 0; i < argc; i++)
391 static int CallStartupWithinTryBlock()
396 ret = MAIN_STARTUP();
407 #ifdef NEED_COOKIE_INIT
421 __security_init_cookie();
423 return CallStartupWithinTryBlock();
EXTERN_C int wseh_EntryPoint()
static const size_t DEBUG_SYMBOL_CHARS
Maximum number of characters (including null terminator) written to user's buffers by debug_ResolveSy...
const XTypeInfo * types[1]
ErrorReaction debug_DisplayError(const wchar_t *description, size_t flags, void *context, const wchar_t *lastFuncToSkip, const wchar_t *pathname, int line, const char *func, atomic_bool *suppress)
display an error dialog with a message and stack trace.
std::string utf8_from_wstring(const std::wstring &src, Status *err)
opposite of wstring_from_utf8
void wdbg_sym_WriteMinidump(EXCEPTION_POINTERS *exception_pointers)
const XTypeInfoArray * array
static const wchar_t * GetExceptionDescription(const EXCEPTION_POINTERS *ep, wchar_t *description, size_t maxChars)
ErrorReaction
choices offered by the error dialog that are returned by debug_DisplayError.
intptr_t cpu_AtomicAdd(volatile intptr_t *location, intptr_t increment)
add a signed value to a variable without the possibility of interference from other threads/CPUs...
int swprintf_s(wchar_t *buf, size_t max_chars, const wchar_t *fmt,...) WPRINTF_ARGS(3)
const std::type_info * ti
bool wutil_IsLocked(WinLockId id)
#define DECORATED_NAME(name)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
static const size_t DEBUG_FILE_CHARS
LIB_API void * debug_GetCaller(void *context, const wchar_t *lastFuncToSkip)
return the caller of a certain function on the call stack.
disallow the Continue button.
#define FOURCC_BE(a, b, c, d)
big-endian version of FOURCC
static const wchar_t * GetSehExceptionDescription(const EXCEPTION_RECORD *er, wchar_t *description, size_t maxChars)
#define DEBUG_DISPLAY_ERROR(description)
LIB_API Status debug_ResolveSymbol(void *ptr_of_interest, wchar_t *sym_name, wchar_t *file, int *line)
read and return symbol information for the given address.
int strcpy_s(char *dst, size_t max_dst_chars, const char *src)
static bool IsCppException(const EXCEPTION_RECORD *er)
long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS *ep)
int main(int argc, char *argv[])
static const wchar_t * GetCppExceptionDescription(const EXCEPTION_RECORD *er, wchar_t *description, size_t maxChars)
static void GetExceptionLocus(EXCEPTION_POINTERS *ep, wchar_t *file, int *line, wchar_t *func)
ignore, continue as if nothing happened.