32 PENUMLOADED_MODULES_CALLBACK64, PVOID);
34 PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64,
35 PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64);
62 #define MI_SIZE_V1 584
63 #define MI_SIZE_V2 1664
64 #define MI_SIZE_V3 1672
72 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
73 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
76 #define PRIxx64 "#.16I64x"
77 #define PRIxx32 "#.8I32x"
82 #define WORDxx(x) ((DWORD64)(x))
85 #define WORDxx(x) ((DWORD32)(x))
96 va_start(argptr, fmt);
97 len = wvsprintf(buf, fmt, argptr);
100 if (len > 0 && len < 1024) {
111 IMAGEHLP_MODULE64 moduleInfo;
112 DWORD64 pc = *(DWORD64 *)UserContext;
116 VS_FIXEDFILEINFO *info;
118 char *symbols, *star;
122 len = lstrlen(ModuleName);
123 if (len >= MAX_PATH) {
129 numBytes >=
sizeof(*info)) {
130 info = (VS_FIXEDFILEINFO *)data;
131 wsprintf(version,
"%u.%u.%u.%u",
132 HIWORD(info->dwFileVersionMS),
133 LOWORD(info->dwFileVersionMS),
134 HIWORD(info->dwFileVersionLS),
135 LOWORD(info->dwFileVersionLS));
137 CopyMemory(version,
"unknown", 8);
146 ModuleName = moduleInfo.ModuleName;
147 switch (moduleInfo.SymType) {
148 case SymNone: symbols =
"none";
break;
149 case SymCoff: symbols =
"COFF";
break;
150 case SymPdb: symbols =
"PDB";
break;
151 case SymExport: symbols =
"export";
break;
152 case SymVirtual: symbols =
"virtual";
break;
153 default: symbols =
"unknown";
break;
156 write_report(
"SymGetModuleInfo64 failed with error %#x\r\n",
161 if (pc >= ModuleBase && pc < ModuleBase + ModuleSize) {
169 "%"PRIxx" %"PRIxx" %s (version %s, symbols %s)%s\r\n",
171 ModuleName, version, symbols, star);
176 #define CRASH_TITLE PRODUCT " Unhandled Exception"
182 STACKFRAME64 stackFrame;
183 PEXCEPTION_RECORD exception;
189 BYTE buffer[
sizeof(SYMBOL_INFO) + 256 - 1];
190 IMAGEHLP_MODULE64 moduleInfo;
192 char execdir[MAX_PATH];
193 HMODULE moduleHandle;
194 SYSTEMTIME systemTime;
200 if (prevExceptionFilter) {
201 action = prevExceptionFilter(exceptionInfo);
202 if (action != EXCEPTION_CONTINUE_SEARCH) {
208 if (IsDebuggerPresent()) {
209 return EXCEPTION_CONTINUE_SEARCH;
213 if (GetCurrentThread() != mainProcessThread) {
214 return EXCEPTION_CONTINUE_SEARCH;
222 ret = MessageBox(NULL,
223 PRODUCT
" has encountered an unhandled "
224 "exception and needs to be terminated.\n"
225 "Would you like to generate a crash report?",
227 MB_ICONERROR | MB_YESNO
229 | MB_SERVICE_NOTIFICATION
233 return EXCEPTION_EXECUTE_HANDLER;
238 moduleHandle = LoadLibrary(x); \
239 if (!moduleHandle) { \
240 return EXCEPTION_CONTINUE_SEARCH; \
246 p##y = (x)GetProcAddress(moduleHandle, #y); \
248 return EXCEPTION_CONTINUE_SEARCH; \
271 len = GetModuleFileName(NULL, execdir,
sizeof(execdir));
272 if (!len || len >=
sizeof(execdir)) {
273 return EXCEPTION_CONTINUE_SEARCH;
277 if (execdir[len] ==
'\\') {
282 if (!len || len + 24 >= MAX_PATH) {
283 return EXCEPTION_CONTINUE_SEARCH;
288 CopyMemory(path, execdir, len);
289 CopyMemory(path + len,
"\\Q2RTX_CrashReportXX.txt", 25);
290 for (i = 0; i < 100; i++) {
291 path[len + 18] =
'0' + i / 10;
292 path[len + 19] =
'0' + i % 10;
299 FILE_ATTRIBUTE_NORMAL,
306 if (GetLastError() != ERROR_FILE_EXISTS) {
308 "Couldn't create crash report. "
309 "Base directory is not writable.",
312 return EXCEPTION_EXECUTE_HANDLER;
318 "Couldn't create crash report. "
319 "All report slots are full.\n"
320 "Please remove existing reports from base directory.",
323 return EXCEPTION_EXECUTE_HANDLER;
327 SYMOPT_LOAD_ANYTHING |
329 SYMOPT_FAIL_CRITICAL_ERRORS);
336 GetSystemTime(&systemTime);
338 "Crash report generated %s %u %u, %02u:%02u:%02u UTC\r\n",
346 "by " APPLICATION
" " VERSION_STRING
347 ", built " __DATE__
", " __TIME__
"\r\n");
349 #pragma warning(push)
350 #pragma warning(disable: 4996) // warning C4996: 'GetVersionExA': was declared deprecated
351 vinfo.dwOSVersionInfoSize =
sizeof(vinfo);
352 if (GetVersionEx(&vinfo)) {
354 "\r\nWindows version: %u.%u (build %u) %s\r\n",
355 vinfo.dwMajorVersion,
356 vinfo.dwMinorVersion,
367 for (i = 0; i < 4; i++) {
369 if (i && len >=
sizeof(moduleInfo)) {
372 moduleInfo.SizeOfStruct = len;
380 "Module info size is %u (not %u)\r\n",
395 exception = exceptionInfo->ExceptionRecord;
396 context = exceptionInfo->ContextRecord;
411 write_report(
"EnumerateLoadedModules64 failed with error %#x\r\n",
416 write_report(
"Code: %#08x\r\n", exception->ExceptionCode);
442 ZeroMemory(&stackFrame,
sizeof(stackFrame));
444 stackFrame.AddrPC.Offset =
context->Rip;
445 stackFrame.AddrFrame.Offset =
context->Rbp;
446 stackFrame.AddrStack.Offset =
context->Rsp;
448 stackFrame.AddrPC.Offset =
context->Eip;
449 stackFrame.AddrFrame.Offset =
context->Ebp;
450 stackFrame.AddrStack.Offset =
context->Esp;
452 stackFrame.AddrPC.Mode = AddrModeFlat;
453 stackFrame.AddrFrame.Mode = AddrModeFlat;
454 stackFrame.AddrStack.Mode = AddrModeFlat;
458 symbol = (SYMBOL_INFO *)buffer;
459 symbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
460 symbol->MaxNameLen = 256;
463 IMAGE_FILE_MACHINE_AMD64,
465 IMAGE_FILE_MACHINE_I386,
478 WORDxx(stackFrame.Params[0]),
479 WORDxx(stackFrame.Params[1]),
480 WORDxx(stackFrame.Params[2]),
481 WORDxx(stackFrame.Params[3]));
486 stackFrame.AddrPC.Offset,
488 if (moduleInfo.SymType != SymNone &&
489 moduleInfo.SymType != SymExport &&
492 stackFrame.AddrPC.Offset,
496 moduleInfo.ModuleName,
497 symbol->Name, (DWORD32)offset);
500 moduleInfo.ModuleName,
501 WORDxx(stackFrame.AddrPC.Offset));
505 WORDxx(stackFrame.AddrPC.Offset));
517 return EXCEPTION_EXECUTE_HANDLER;