std::string ResourceCompiler::Directory_To_Output_Directory(std::string directory) { Platform* platform = Platform::Get(); std::string path = Platform::Get()->Join_Path(".compiled", directory); if (!platform->Is_Directory(path.c_str())) { platform->Create_Directory(path.c_str(), true); } return path; }
LONG WINAPI ExceptionHandler(struct _EXCEPTION_POINTERS *exceptionInfo) { Platform* platform = Platform::Get(); std::string dump_dir = platform->Get_Working_Dir() + "\\.crashes"; std::string dump_path = dump_dir + "\\00000000.dmp"; DBG_LOG("~~~~~~~~~~~~ UNHANDLED EXCEPTION OCCURRED ~~~~~~~~~~~"); // Make sure dump file exists. if (!platform->Is_Directory(dump_dir.c_str())) { DBG_LOG("Attempt to create dump folder ..."); DBG_LOG("Path: %s", dump_dir.c_str()); if (!platform->Create_Directory(dump_dir.c_str(), true)) { DBG_LOG("Failed to create dump folder. Aborting."); exit(0); } } // Find somewhere to dump the file. unsigned int index = 0; do { dump_path = dump_dir + "\\" + StringHelper::To_String(index) + ".dmp"; index++; } while (platform->Is_File(dump_path.c_str())); // Dump the file! DBG_LOG("Attempt to create dump file ..."); DBG_LOG("Path: %s", dump_path.c_str()); HANDLE fileHandle = CreateFileA(dump_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle == NULL) { DBG_LOG("Failed to create open dump file. Aborting."); exit(0); } // Duuuuuuuuump. HANDLE process = GetCurrentProcess(); MINIDUMP_EXCEPTION_INFORMATION exceptionParam; exceptionParam.ThreadId = GetCurrentThreadId(); exceptionParam.ExceptionPointers = exceptionInfo; exceptionParam.ClientPointers = FALSE; EnterCriticalSection(&g_dbghelp_critical_section); BOOL result = MiniDumpWriteDump(process, GetCurrentProcessId(), fileHandle, MiniDumpNormal, exceptionInfo == NULL ? NULL : &exceptionParam, NULL, NULL); LeaveCriticalSection(&g_dbghelp_critical_section); // Close the dump file handle. CloseHandle(fileHandle); // Check a file was created. if (result == FALSE) { u32 ec = GetLastError(); DBG_LOG("Failed to create dump file, GetLastError()=%i (%s)", ec, FormatSystemError(ec).c_str()); } else { DBG_LOG("Success!"); } // Dump stack trace. DBG_LOG(""); DBG_LOG("Call Stack:"); StackFrame frames[256]; int frameCount = platform->Get_Stack_Trace(frames, 256, exceptionInfo); for (int i = 0; i < frameCount; i++) { StackFrame& frame = frames[i]; platform->Resolve_Stack_Frame_Info(frame); DBG_LOG("[%i] %s (%i): %s", i, frame.File, frame.Line, frame.Name); } DBG_LOG(""); // Bail the f**k out. // We use this to long jump back to the point after PlatformMain is called // so we can deinitialize everything. if (GetCurrentThreadId() == g_main_thread_id) { DBG_LOG("Attempting recovery through longjmp ..."); longjmp(g_error_recovery_longjmp, 1); } return EXCEPTION_EXECUTE_HANDLER; }