aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/callstack.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-09-26 16:45:54 +0200
committerGitHub Enterprise <[email protected]>2025-09-26 16:45:54 +0200
commitd22b84461e4f1a9dd77c8f93488a6914a2436090 (patch)
treeaeb4ed5312c500cb649dea427e30638070303ede /src/zencore/callstack.cpp
parentfix for C4244 truncation warning (#515) (diff)
downloadzen-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/zencore/callstack.cpp')
-rw-r--r--src/zencore/callstack.cpp48
1 files changed, 48 insertions, 0 deletions
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<char, 2048> 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")