diff options
| author | Dan Engelbrecht <[email protected]> | 2025-09-26 16:45:54 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-09-26 16:45:54 +0200 |
| commit | d22b84461e4f1a9dd77c8f93488a6914a2436090 (patch) | |
| tree | aeb4ed5312c500cb649dea427e30638070303ede /src/zenutil/logging.cpp | |
| parent | fix for C4244 truncation warning (#515) (diff) | |
| download | zen-d22b84461e4f1a9dd77c8f93488a6914a2436090.tar.xz zen-d22b84461e4f1a9dd77c8f93488a6914a2436090.zip | |
Make sure we call the previous terminate handle if present when we intercept terminate calls (#514)
Improvement: Make sure we call the previous terminate handle if present when we intercept terminate calls
Improvement: Avoid allocating memory for call stack in terminate handle and assert callback
Diffstat (limited to 'src/zenutil/logging.cpp')
| -rw-r--r-- | src/zenutil/logging.cpp | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/src/zenutil/logging.cpp b/src/zenutil/logging.cpp index 8ff58ee73..806b96d52 100644 --- a/src/zenutil/logging.cpp +++ b/src/zenutil/logging.cpp @@ -42,6 +42,8 @@ InitializeLogging(const LoggingOptions& LogOptions) FinishInitializeLogging(LogOptions); } +static std::terminate_handler OldTerminateHandler = nullptr; + void BeginInitializeLogging(const LoggingOptions& LogOptions) { @@ -99,12 +101,43 @@ BeginInitializeLogging(const LoggingOptions& LogOptions) } } - std::set_terminate([]() { - void* Frames[8]; - uint32_t FrameCount = GetCallstack(2, 8, Frames); - CallstackFrames* Callstack = CreateCallstack(FrameCount, Frames); - ZEN_CRITICAL("Program exited abnormally via std::terminate()\n{}", CallstackToString(Callstack, " ")); - FreeCallstack(Callstack); + OldTerminateHandler = std::set_terminate([]() { + try + { + constexpr int SkipFrameCount = 4; + constexpr int FrameCount = 8; + uint8_t CallstackBuffer[CallstackRawMemorySize(SkipFrameCount, FrameCount)]; + CallstackFrames* Callstack = GetCallstackRaw(&CallstackBuffer[0], SkipFrameCount, FrameCount); + + fmt::basic_memory_buffer<char, 2048> Message; + auto Appender = fmt::appender(Message); + fmt::format_to(Appender, "Program exited abnormally via std::terminate()"); + + if (Callstack->FrameCount > 0) + { + fmt::format_to(Appender, "\n"); + + CallstackToStringRaw(Callstack, &Message, [](void* UserData, uint32_t FrameIndex, const char* FrameText) { + ZEN_UNUSED(FrameIndex); + fmt::basic_memory_buffer<char, 2048>* Message = (fmt::basic_memory_buffer<char, 2048>*)UserData; + auto Appender = fmt::appender(*Message); + fmt::format_to(Appender, " {}\n", FrameText); + }); + } + Message.push_back('\0'); + + // We use direct ZEN_LOG here instead of ZEN_ERROR as we don't care about *this* code location in the log + ZEN_LOG(Log(), zen::logging::level::Critical, "{}", Message.data()); + zen::logging::FlushLogging(); + } + catch (const std::exception&) + { + // Ignore any exceptions in terminate callback + } + if (OldTerminateHandler) + { + OldTerminateHandler(); + } }); // Default |