diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 250c5b03e8..a32366cefa 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -109,7 +109,7 @@ static bool truncate_file(const std::string& file, u64 length) #else #include #endif -#include "errno.h" +#include #define GET_API_ERROR static_cast(errno) @@ -839,7 +839,7 @@ std::string fs::get_executable_dir() wchar_t buf[2048]; if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1) { - MessageBoxA(0, fmt::format("GetModuleFileName() failed: 0x%x.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR); + MessageBoxA(0, fmt::format("GetModuleFileName() failed (0x%x).", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR); return dir; // empty } diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 11d2fc6def..306ef4305b 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -19,26 +19,33 @@ #include #endif -static const auto s_terminate_handler_set = std::set_terminate([]() +void report_fatal_error(const std::string& msg) { - if (std::uncaught_exception()) +#ifdef _WIN32 + const auto& text = msg + "\n\nPlease report this error to the developers. Press (Ctrl+C) to copy this message."; + MessageBoxA(0, text.c_str(), "Fatal error", MB_ICONERROR); // TODO: unicode message +#else + std::printf("Fatal error: %s\nPlease report this error to the developers.\n", msg.c_str()); +#endif +} + +[[noreturn]] void catch_all_exceptions() +{ + try { - try - { - throw; - } - catch (const std::exception& ex) - { - std::printf("Unhandled exception: %s\n", ex.what()); - } - catch (...) - { - std::printf("Unhandled exception of unknown type.\n"); - } + throw; + } + catch (const std::exception& ex) + { + report_fatal_error("Unhandled exception: "s + ex.what()); + } + catch (...) + { + report_fatal_error("Unhandled exception (unknown)"); } std::abort(); -}); +} void SetCurrentThreadDebugName(const char* threadName) { @@ -1158,7 +1165,7 @@ const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_PO const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG { - std::string msg; + std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode); if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { @@ -1184,11 +1191,10 @@ const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTE } } - msg += fmt::format("Image base: %p.\n\n", GetModuleHandle(NULL)); - msg += "Report this error to the developers. Press (Ctrl+C) to copy this message."; + msg += fmt::format("Image base: %p.", GetModuleHandle(NULL)); // Report fatal error - MessageBoxA(0, msg.c_str(), fmt::format("Win32 Exception 0x%08X", pExp->ExceptionRecord->ExceptionCode).c_str(), MB_ICONERROR); + report_fatal_error(msg); return EXCEPTION_CONTINUE_SEARCH; }); @@ -1218,8 +1224,8 @@ void signal_handler(int sig, siginfo_t* info, void* uct) } else { - // Report fatal error (TODO) - std::printf("Access violation %s location %p at %p.\n", cause, info->si_addr, RIP(context)); + // TODO (debugger interaction) + report_fatal_error(fmt::format("Access violation %s location %p at %p.", cause, info->si_addr, RIP(context))); std::abort(); } } @@ -1253,8 +1259,8 @@ void thread_ctrl::initialize() if (g_sigaction_result == -1) #endif { - std::printf("Exceptions handlers are not set correctly.\n"); - std::terminate(); + report_fatal_error("Exception handler is not set correctly."); + std::abort(); } // TODO @@ -1286,12 +1292,9 @@ thread_ctrl::~thread_ctrl() { m_future.get(); } - catch (const std::exception& ex) - { - LOG_ERROR(GENERAL, "Abandoned exception: %s", ex.what()); - } - catch (EmulationStopped) + catch (...) { + catch_all_exceptions(); } } } @@ -1310,7 +1313,7 @@ std::string named_thread_t::get_name() const void named_thread_t::start() { - CHECK_ASSERTION(m_thread == nullptr); + CHECK_ASSERTION(!m_thread); // Get shared_ptr instance (will throw if called from the constructor or the object has been created incorrectly) auto ptr = shared_from_this(); @@ -1348,7 +1351,7 @@ void named_thread_t::start() } catch (const std::exception& e) { - LOG_ERROR(GENERAL, "Exception: %s", e.what()); + LOG_ERROR(GENERAL, "Exception: %s\nPlease report this to the developers.", e.what()); Emu.Pause(); } catch (EmulationStopped) diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 1ceb587e73..557a83d7a0 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -1,5 +1,8 @@ #pragma once +// Will report exception and call std::abort() if put in catch(...) +[[noreturn]] void catch_all_exceptions(); + // Thread control class class thread_ctrl final { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 283e5bfe58..83add764ba 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -16,6 +16,7 @@ #include #include #include +#include /* OS X uses MAP_ANON instead of MAP_ANONYMOUS */ #ifndef MAP_ANONYMOUS @@ -46,8 +47,8 @@ namespace vm if (memory_handle == NULL) { - std::printf("CreateFileMapping() failed\n"); - return{}; + MessageBoxA(0, fmt::format("CreateFileMapping() failed (0x%x).", GetLastError()).c_str(), "vm::initialize()", MB_ICONERROR); + std::abort(); } mapped_ptr_t base_addr(static_cast(::MapViewOfFile(memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000))); @@ -59,15 +60,15 @@ namespace vm if (memory_handle == -1) { - std::printf("shm_open('/rpcs3_vm') failed\n"); - return{}; + std::printf("shm_open('/rpcs3_vm') failed (%d).\n", errno); + std::abort(); } if (::ftruncate(memory_handle, 0x100000000) == -1) { - std::printf("ftruncate(memory_handle) failed\n"); + std::printf("ftruncate(memory_handle) failed (%d).\n", errno); ::shm_unlink("/rpcs3_vm"); - return{}; + std::abort(); } mapped_ptr_t base_addr(static_cast(::mmap(nullptr, 0x100000000, PROT_NONE, MAP_SHARED, memory_handle, 0))); @@ -76,7 +77,7 @@ namespace vm ::shm_unlink("/rpcs3_vm"); #endif - std::printf("vm: base_addr = %p, priv_addr = %p\n", base_addr.get(), priv_addr.get()); + std::printf("vm::g_base_addr = %p\nvm::g_priv_addr = %p\n", base_addr.get(), priv_addr.get()); return{ std::move(base_addr), std::move(priv_addr) }; }