From d22b84461e4f1a9dd77c8f93488a6914a2436090 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Fri, 26 Sep 2025 16:45:54 +0200 Subject: 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 --- src/zencore/callstack.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/zencore/callstack.cpp') diff --git a/src/zencore/callstack.cpp b/src/zencore/callstack.cpp index b22f2ec1f..8aa1111bf 100644 --- a/src/zencore/callstack.cpp +++ b/src/zencore/callstack.cpp @@ -210,6 +210,54 @@ CallstackToString(const CallstackFrames* Callstack, std::string_view Prefix) return SB.ToString(); } +void +CallstackToStringRaw(const CallstackFrames* Callstack, void* CallbackUserData, CallstackRawCallback Callback) +{ + if (Callstack && Callstack->FrameCount > 0) + { +#if ZEN_PLATFORM_WINDOWS + char SymbolBuffer[sizeof(SYMBOL_INFO) + 1024]; + SYMBOL_INFO* SymbolInfo = (SYMBOL_INFO*)SymbolBuffer; + SymbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO); + SymbolInfo->MaxNameLen = 1023; + DWORD64 Displacement = 0; + fmt::basic_memory_buffer Message; + for (uint32_t FrameIndex = 0; FrameIndex < Callstack->FrameCount; FrameIndex++) + { + if (WinSymbols.GetSymbol(Callstack->Frames[FrameIndex], SymbolInfo, Displacement)) + { + auto Appender = fmt::appender(Message); + fmt::format_to(Appender, "{}+{:#x} [{:#x}]", SymbolInfo->Name, Displacement, (uintptr_t)Callstack->Frames[FrameIndex]); + Message.push_back('\0'); + Callback(CallbackUserData, FrameIndex, Message.data()); + Message.resize(0); + } + } +#endif +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + char** messages = backtrace_symbols(Callstack->Frames, (int)Callstack->FrameCount); + if (messages) + { + for (uint32_t FrameIndex = 0; FrameIndex < Callstack->FrameCount; FrameIndex++) + { + Callback(CallbackUserData, FrameIndex, messages[FrameIndex]); + } + free(messages); + } +#endif + } +} + +CallstackFrames* +GetCallstackRaw(void* CaptureBuffer, int FramesToSkip, int FramesToCapture) +{ + CallstackFrames* Callstack = (CallstackFrames*)CaptureBuffer; + + Callstack->Frames = (void**)&Callstack[1]; + Callstack->FrameCount = GetCallstack(FramesToSkip, FramesToCapture, Callstack->Frames); + return Callstack; +} + #if ZEN_WITH_TESTS TEST_CASE("Callstack.Basic") -- cgit v1.2.3