Merge pull request #64 from georgemoralis/logging_exception
log exceptions and flush log file
This commit is contained in:
commit
bb49254fad
|
@ -7,8 +7,53 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Util/config.h>
|
#include <Util/config.h>
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
namespace logging {
|
namespace logging {
|
||||||
std::vector<spdlog::sink_ptr> sinks;
|
std::vector<spdlog::sink_ptr> 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 u32 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 ({:#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;
|
||||||
|
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) {
|
int init(bool use_stdout) {
|
||||||
sinks.clear(); // clear existing sinks
|
sinks.clear(); // clear existing sinks
|
||||||
|
@ -20,6 +65,23 @@ int init(bool use_stdout) {
|
||||||
spdlog::set_formatter(std::move(f));
|
spdlog::set_formatter(std::move(f));
|
||||||
spdlog::set_level(static_cast<spdlog::level::level_enum>(Config::getLogLevel()));
|
spdlog::set_level(static_cast<spdlog::level::level_enum>(Config::getLogLevel()));
|
||||||
spdlog::level::level_enum t = spdlog::get_level();
|
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
|
return 0; // all ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue