2
0
Эх сурвалжийг харах

Try to handle uncaught c++ exception on Windows and create crashdump

Ivan Savenko 1 жил өмнө
parent
commit
79d568b17b
1 өөрчлөгдсөн 57 нэмэгдсэн , 21 устгасан
  1. 57 21
      lib/CConsoleHandler.cpp

+ 57 - 21
lib/CConsoleHandler.cpp

@@ -109,25 +109,8 @@ const char* exceptionName(DWORD exc)
 #undef EXC_CASE
 }
 
-
-
-LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
+static void createMemoryDump(MINIDUMP_EXCEPTION_INFORMATION * meinfo)
 {
-	logGlobal->error("Disaster happened.");
-
-	PEXCEPTION_RECORD einfo = exception->ExceptionRecord;
-	logGlobal->error("Reason: 0x%x - %s at %04x:%x", einfo->ExceptionCode, exceptionName(einfo->ExceptionCode), exception->ContextRecord->SegCs, (void*)einfo->ExceptionAddress);
-
-	if (einfo->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
-	{
-		logGlobal->error("Attempt to %s 0x%8x", (einfo->ExceptionInformation[0] == 1 ? "write to" : "read from"), (void*)einfo->ExceptionInformation[1]);
-	}
-	const DWORD threadId = ::GetCurrentThreadId();
-	logGlobal->error("Thread ID: %d", threadId);
-
-	//exception info to be placed in the dump
-	MINIDUMP_EXCEPTION_INFORMATION meinfo = {threadId, exception, TRUE};
-
 	//create file where dump will be placed
 	char *mname = nullptr;
 	char buffer[MAX_PATH + 1];
@@ -142,9 +125,9 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 	strcat(mname, "_crashinfo.dmp");
 	HANDLE dfile = CreateFileA(mname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
 	logGlobal->error("Crash info will be put in %s", mname);
-	
+
 	auto dumpType = MiniDumpWithDataSegs;
-	
+
 	if(settings["general"]["extraDump"].Bool())
 	{
 		dumpType = (MINIDUMP_TYPE)(
@@ -155,8 +138,60 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 			| MiniDumpWithThreadInfo);
 	}
 
-	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dfile, dumpType, &meinfo, 0, 0);
+	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dfile, dumpType, meinfo, 0, 0);
 	MessageBoxA(0, "VCMI has crashed. We are sorry. File with information about encountered problem has been created.", "VCMI Crashhandler", MB_OK | MB_ICONERROR);
+}
+
+static void onTerminate()
+{
+	logGlobal->error("Disaster happened.");
+	try
+	{
+		std::exception_ptr eptr{std::current_exception()};
+		if (eptr)
+		{
+			std::rethrow_exception(eptr);
+		}
+		else
+		{
+			logGlobal->error("...but no current exception found!");
+		}
+	}
+	catch (const std::exception& exc)
+	{
+		logGlobal->error("Reason: %s", exc.what());
+	}
+	catch (...)
+	{
+		logGlobal->error("Reason: unknown exception!");
+	}
+
+	const DWORD threadId = ::GetCurrentThreadId();
+	logGlobal->error("Thread ID: %d", threadId);
+
+	createMemoryDump(nullptr);
+	std::abort();
+}
+
+LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
+{
+	logGlobal->error("Disaster happened.");
+
+	PEXCEPTION_RECORD einfo = exception->ExceptionRecord;
+	logGlobal->error("Reason: 0x%x - %s at %04x:%x", einfo->ExceptionCode, exceptionName(einfo->ExceptionCode), exception->ContextRecord->SegCs, (void*)einfo->ExceptionAddress);
+
+	if (einfo->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
+	{
+		logGlobal->error("Attempt to %s 0x%8x", (einfo->ExceptionInformation[0] == 1 ? "write to" : "read from"), (void*)einfo->ExceptionInformation[1]);
+	}
+	const DWORD threadId = ::GetCurrentThreadId();
+	logGlobal->error("Thread ID: %d", threadId);
+
+	//exception info to be placed in the dump
+	MINIDUMP_EXCEPTION_INFORMATION meinfo = {threadId, exception, TRUE};
+
+	createMemoryDump(&meinfo);
+
 	return EXCEPTION_EXECUTE_HANDLER;
 }
 #endif
@@ -254,6 +289,7 @@ CConsoleHandler::CConsoleHandler():
 	defErrColor = csbi.wAttributes;
 #ifndef _DEBUG
 	SetUnhandledExceptionFilter(onUnhandledException);
+	std::set_terminate(onTerminate);
 #endif
 #else
 	defColor = "\x1b[0m";