From ceeda057981c4627470a4454603fbc3da19b74f8 Mon Sep 17 00:00:00 2001 From: SachinVin <26602104+SachinVin@users.noreply.github.com> Date: Sun, 12 Nov 2023 01:25:42 +0530 Subject: [PATCH] assert/logging: Stop the logging thread and flush the backends before crashing (#7146) --- src/common/assert.h | 5 +++++ src/common/logging/backend.cpp | 17 +++++++++++++++++ src/common/logging/backend.h | 3 +++ 3 files changed, 25 insertions(+) diff --git a/src/common/assert.h b/src/common/assert.h index b5ec4fe47..5f632a5c6 100644 --- a/src/common/assert.h +++ b/src/common/assert.h @@ -6,6 +6,7 @@ #include #include "common/common_funcs.h" +#include "common/logging/backend.h" #include "common/logging/log.h" // For asserts we'd like to keep all the junk executed when an assert happens away from the @@ -17,6 +18,7 @@ if (!(_a_)) [[unlikely]] { \ []() CITRA_NO_INLINE CITRA_NO_RETURN { \ LOG_CRITICAL(Debug, "Assertion Failed!"); \ + Common::Log::Stop(); \ Crash(); \ exit(1); \ }(); \ @@ -28,6 +30,7 @@ if (!(_a_)) [[unlikely]] { \ [&]() CITRA_NO_INLINE CITRA_NO_RETURN { \ LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ + Common::Log::Stop(); \ Crash(); \ exit(1); \ }(); \ @@ -37,6 +40,7 @@ #define UNREACHABLE() \ ([]() CITRA_NO_INLINE CITRA_NO_RETURN { \ LOG_CRITICAL(Debug, "Unreachable code!"); \ + Common::Log::Stop(); \ Crash(); \ exit(1); \ }()) @@ -44,6 +48,7 @@ #define UNREACHABLE_MSG(...) \ ([&]() CITRA_NO_INLINE CITRA_NO_RETURN { \ LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); \ + Common::Log::Stop(); \ Crash(); \ exit(1); \ }()) diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index f39c79dea..1ea126eaa 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -220,6 +220,10 @@ public: instance->StartBackendThread(); } + static void Stop() { + instance->StopBackendThread(); + } + Impl(const Impl&) = delete; Impl& operator=(const Impl&) = delete; @@ -330,6 +334,15 @@ private: }); } + void StopBackendThread() { + backend_thread.request_stop(); + if (backend_thread.joinable()) { + backend_thread.join(); + } + + ForEachBackend([](Backend& backend) { backend.Flush(); }); + } + Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, const char* function, std::string&& message) const { using std::chrono::duration_cast; @@ -421,6 +434,10 @@ void Start() { Impl::Start(); } +void Stop() { + Impl::Stop(); +} + void DisableLoggingInTests() { initialization_in_progress_suppress_logging = true; } diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index 19a5ef0f4..8b664af36 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h @@ -16,6 +16,9 @@ void Initialize(std::string_view log_file = ""); void Start(); +/// Explictily stops the logger thread and flushes the buffers +void Stop(); + void DisableLoggingInTests(); /**