From 2f0fec806a1a1b8f2a10a9095fe51e17e5875d65 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 27 Oct 2023 18:57:48 +0300 Subject: [PATCH 1/4] log exceptions and flush log file --- src/Util/log.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/Util/log.cpp b/src/Util/log.cpp index a9c262aa..45407c1f 100644 --- a/src/Util/log.cpp +++ b/src/Util/log.cpp @@ -7,8 +7,53 @@ #include #include +#ifdef _WIN64 +#include +#endif + +#include "log.h" + namespace logging { std::vector sinks; +constexpr bool log_file_exceptions = true; // disable it to disable logging + +void flush() { spdlog::details::registry::instance().flush_all(); } + +#ifdef _WIN64 + +static LONG WINAPI exception_handler(PEXCEPTION_POINTERS pExp) noexcept { + const unsigned ec = pExp->ExceptionRecord->ExceptionCode; + switch (ec) { + case EXCEPTION_ACCESS_VIOLATION: + LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ACCESS_VIOLATION ({}). ", log_hex(ec)); + switch (pExp->ExceptionRecord->ExceptionInformation[0]) { + case 0: LOG_CRITICAL_IF(log_file_exceptions,"Read violation at address {}.", log_hex(pExp->ExceptionRecord->ExceptionInformation[1])); break; + case 1: LOG_CRITICAL_IF(log_file_exceptions,"Write violation at address {}.", log_hex(pExp->ExceptionRecord->ExceptionInformation[1])); break; + case 8:LOG_CRITICAL_IF(log_file_exceptions,"DEP violation at address {}.", log_hex(pExp->ExceptionRecord->ExceptionInformation[1])); break; + default: break; + } + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({}). ", log_hex(ec)); break; + case EXCEPTION_DATATYPE_MISALIGNMENT: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_DATATYPE_MISALIGNMENT ({}). ", log_hex(ec)); break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({}). ", log_hex(ec)); break; + case EXCEPTION_ILLEGAL_INSTRUCTION: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ILLEGAL_INSTRUCTION ({}). ", log_hex(ec)); break; + case EXCEPTION_IN_PAGE_ERROR: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_IN_PAGE_ERROR ({}). ", log_hex(ec)); break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_INT_DIVIDE_BY_ZERO ({}). ", log_hex(ec)); break; + case EXCEPTION_PRIV_INSTRUCTION: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_PRIV_INSTRUCTION ({}). ", log_hex(ec)); break; + case EXCEPTION_STACK_OVERFLOW: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_STACK_OVERFLOW ({}). ", log_hex(ec)); break; + default: return EXCEPTION_CONTINUE_SEARCH; + } + flush(); + return EXCEPTION_CONTINUE_SEARCH; +} + +void register_log_exception_handler() { + if (!AddVectoredExceptionHandler(0, exception_handler)) { + LOG_CRITICAL_IF(log_file_exceptions,"Failed to register an exception handler"); + } +} +#endif + int init(bool use_stdout) { sinks.clear(); // clear existing sinks @@ -20,9 +65,28 @@ int init(bool use_stdout) { spdlog::set_formatter(std::move(f)); spdlog::set_level(static_cast(Config::getLogLevel())); spdlog::level::level_enum t = spdlog::get_level(); + + #ifdef _WIN64 + register_log_exception_handler(); + #endif + static std::terminate_handler old_terminate = nullptr; + old_terminate = std::set_terminate([]() { + try { + std::rethrow_exception(std::current_exception()); + } catch (const std::exception &e) { + LOG_CRITICAL_IF(log_file_exceptions, "Unhandled C++ exception. {}", e.what()); + } catch (...) { + LOG_CRITICAL_IF(log_file_exceptions, "Unhandled C++ exception. UNKNOWN"); + } + flush(); + if (old_terminate) old_terminate(); + }); + return 0; // all ok } + + void set_level(spdlog::level::level_enum log_level) { spdlog::set_level(log_level); } } // namespace logging \ No newline at end of file From ff2a9dd37a2d2796fa78641b5d21d1a28893ad19 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 27 Oct 2023 20:55:18 +0300 Subject: [PATCH 2/4] Update src/Util/log.cpp Co-authored-by: GPUCode <47210458+GPUCode@users.noreply.github.com> --- src/Util/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Util/log.cpp b/src/Util/log.cpp index 45407c1f..1487b81b 100644 --- a/src/Util/log.cpp +++ b/src/Util/log.cpp @@ -22,7 +22,7 @@ void flush() { spdlog::details::registry::instance().flush_all(); } #ifdef _WIN64 static LONG WINAPI exception_handler(PEXCEPTION_POINTERS pExp) noexcept { - const unsigned ec = pExp->ExceptionRecord->ExceptionCode; + const u32 ec = pExp->ExceptionRecord->ExceptionCode; switch (ec) { case EXCEPTION_ACCESS_VIOLATION: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ACCESS_VIOLATION ({}). ", log_hex(ec)); From 4706b6b4e55520b75646cfa354691f027776e6cc Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Fri, 27 Oct 2023 20:56:21 +0300 Subject: [PATCH 3/4] Update src/Util/log.cpp Co-authored-by: GPUCode <47210458+GPUCode@users.noreply.github.com> --- src/Util/log.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Util/log.cpp b/src/Util/log.cpp index 1487b81b..8489e72b 100644 --- a/src/Util/log.cpp +++ b/src/Util/log.cpp @@ -85,8 +85,6 @@ int init(bool use_stdout) { return 0; // all ok } - - void set_level(spdlog::level::level_enum log_level) { spdlog::set_level(log_level); } } // namespace logging \ No newline at end of file From f1ddf028c2c971071750bfeadfd12ec55e00ae89 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 28 Oct 2023 00:09:47 +0300 Subject: [PATCH 4/4] Update src/Util/log.cpp Co-authored-by: GPUCode <47210458+GPUCode@users.noreply.github.com> --- src/Util/log.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Util/log.cpp b/src/Util/log.cpp index 8489e72b..4b2b91ed 100644 --- a/src/Util/log.cpp +++ b/src/Util/log.cpp @@ -33,7 +33,7 @@ static LONG WINAPI exception_handler(PEXCEPTION_POINTERS pExp) noexcept { default: break; } break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({}). ", log_hex(ec)); break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ARRAY_BOUNDS_EXCEEDED ({:#x}). ", ec); break; case EXCEPTION_DATATYPE_MISALIGNMENT: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_DATATYPE_MISALIGNMENT ({}). ", log_hex(ec)); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_FLT_DIVIDE_BY_ZERO ({}). ", log_hex(ec)); break; case EXCEPTION_ILLEGAL_INSTRUCTION: LOG_CRITICAL_IF(log_file_exceptions,"Exception EXCEPTION_ILLEGAL_INSTRUCTION ({}). ", log_hex(ec)); break;