6 #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__OpenBSD__) && !defined(__vita__) && !defined(__SWITCH__) && \
7 !defined(__ANDROID__) && !defined(__HAIKU__) && !defined(__EMSCRIPTEN__)
12 static void lwBacktracePrint(
void)
15 int size = backtrace(earray, 100);
17 char **stack = backtrace_symbols(earray, size);
19 for (
int i = 0; i < size; i++)
25 static void lwCrashHandler(
int sig)
27 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Oops, crashed with signal %d :(", sig);
34 #elif defined(_WIN32) && defined(_M_X64)
40 static const char *lwPrintExceptionName(DWORD exception_code)
42 switch (exception_code)
44 case EXCEPTION_ACCESS_VIOLATION:
45 return "Access violation";
46 case EXCEPTION_DATATYPE_MISALIGNMENT:
47 return "Datatype misalignment";
48 case EXCEPTION_BREAKPOINT:
50 case EXCEPTION_SINGLE_STEP:
52 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
53 return "Array bounds exceeded";
54 case EXCEPTION_FLT_DENORMAL_OPERAND:
55 return "Float denormal operand";
56 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
57 return "Float divide by zero";
58 case EXCEPTION_FLT_INEXACT_RESULT:
59 return "Float inexact result";
60 case EXCEPTION_FLT_INVALID_OPERATION:
61 return "Float invalid operation";
62 case EXCEPTION_FLT_OVERFLOW:
63 return "Float overflow";
64 case EXCEPTION_FLT_STACK_CHECK:
65 return "Float stack check";
66 case EXCEPTION_FLT_UNDERFLOW:
67 return "Float underflow";
68 case EXCEPTION_INT_DIVIDE_BY_ZERO:
69 return "Integer divide by zero";
70 case EXCEPTION_INT_OVERFLOW:
71 return "Integer overflow";
72 case EXCEPTION_PRIV_INSTRUCTION:
73 return "Privileged instruction";
74 case EXCEPTION_IN_PAGE_ERROR:
75 return "In page error";
76 case EXCEPTION_ILLEGAL_INSTRUCTION:
77 return "Illegal instruction";
78 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
79 return "Noncontinuable exception";
80 case EXCEPTION_STACK_OVERFLOW:
81 return "Stack overflow";
82 case EXCEPTION_INVALID_DISPOSITION:
83 return "Invalid disposition";
84 case EXCEPTION_GUARD_PAGE:
86 case EXCEPTION_INVALID_HANDLE:
87 return "Invalid handle";
89 return "Unknown exception";
92 static void lwSystemError(
const char *title,
const char *text) { MessageBox(NULL, text, title, MB_OK | MB_ICONERROR); }
98 static void lwPrintStacktrace(LPEXCEPTION_POINTERS e)
100 PIMAGEHLP_SYMBOL64 pSym;
102 DWORD64 dwModBase, Disp64;
105 IMAGEHLP_LINE64 line;
106 const char *filename = NULL;
107 unsigned int linenum = 0;
108 line.SizeOfStruct =
sizeof(IMAGEHLP_LINE64);
110 char modname[MAX_PATH];
111 pSym = (PIMAGEHLP_SYMBOL64)GlobalAlloc(GMEM_FIXED, 16384);
112 ZeroMemory(&sf,
sizeof(sf));
113 sf.AddrPC.Mode = AddrModeFlat;
114 sf.AddrStack.Mode = AddrModeFlat;
115 sf.AddrFrame.Mode = AddrModeFlat;
116 sf.AddrReturn.Mode = AddrModeFlat;
118 PCONTEXT context = e->ContextRecord;
119 DWORD machine_type = 0;
120 sf.AddrPC.Offset = context->Rip;
121 sf.AddrFrame.Offset = context->Rbp;
122 sf.AddrStack.Offset = context->Rsp;
123 machine_type = IMAGE_FILE_MACHINE_AMD64;
126 LOG(
LOG_ERROR) <<
"Exception [" << lwPrintExceptionName(e->ExceptionRecord->ExceptionCode) <<
"] 0x" << std::hex
127 << (
unsigned int)e->ExceptionRecord->ExceptionCode;
128 LOG(
LOG_ERROR) <<
"Exception Address: 0x" << std::hex << e->ExceptionRecord->ExceptionAddress;
135 more = StackWalk(machine_type, GetCurrentProcess(), GetCurrentThread(), &sf, context, NULL, SymFunctionTableAccess64,
136 SymGetModuleBase64, NULL);
137 if (!more || sf.AddrFrame.Offset == 0)
141 dwModBase = SymGetModuleBase64(GetCurrentProcess(), sf.AddrPC.Offset);
144 GetModuleFileName((HINSTANCE)dwModBase, modname, MAX_PATH);
148 strcpy(modname,
"Unknown");
151 pSym->SizeOfStruct =
sizeof(IMAGEHLP_SYMBOL);
152 pSym->MaxNameLength = MAX_PATH;
155 if (SymGetSymFromAddr64(GetCurrentProcess(), sf.AddrPC.Offset, &Disp64, pSym))
157 int filelineinfo_ok = SymGetLineFromAddr64(GetCurrentProcess(), sf.AddrPC.Offset, &Disp, &line);
158 filename = !!filelineinfo_ok ? line.FileName :
"UNKNOWN FILE";
159 linenum = !!filelineinfo_ok ? line.LineNumber : 0;
162 LOG(
LOG_ERROR) << count <<
" " << filename <<
":" << linenum <<
" |" << pSym->Name <<
"+0x" << Disp << std::hex
163 << (
unsigned int)sf.AddrPC.Offset;
168 LOG(
LOG_ERROR) << count <<
" " << modname <<
"+0x" << std::hex << (
unsigned int)sf.AddrPC.Offset;
176 static LONG CALLBACK lwExceptionHandler(LPEXCEPTION_POINTERS e)
182 SymInitialize(GetCurrentProcess(),
".", TRUE);
184 lwPrintStacktrace(e);
187 SymCleanup(GetCurrentProcess());
190 lwSystemError(
"Cytopia has crashed :(",
"There was an unrecoverable error in Cytopia, which will now close.\n\n"
191 "The piece of code that caused the crash has been saved to log.\n\n"
192 "If you can, please create an issue by going to:\n\n"
193 "https://github.com/CytopiaTeam/Cytopia/issues/new \n\n"
194 "Please attatch log and your map to the issue report.\n\n"
195 "With your help, we can avoid this crash in the future.\n\n"
199 return EXCEPTION_EXECUTE_HANDLER;