From 4e190c2e3c3e0c6045bb915537cd70b7be8e98d3 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Sun, 19 Nov 2023 18:04:24 +0100 Subject: [PATCH] Add decoding stack trace function names on Apple platforms --- Source/Engine/Core/Types/StringBuilder.h | 6 ++++ .../Engine/Platform/Apple/ApplePlatform.cpp | 33 ++++++++++++++++--- Source/Engine/Platform/Base/PlatformBase.cpp | 11 +++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/Source/Engine/Core/Types/StringBuilder.h b/Source/Engine/Core/Types/StringBuilder.h index 051554a23..068f245d0 100644 --- a/Source/Engine/Core/Types/StringBuilder.h +++ b/Source/Engine/Core/Types/StringBuilder.h @@ -3,6 +3,7 @@ #pragma once #include "String.h" +#include "StringView.h" #include "Engine/Core/Collections/Array.h" /// @@ -138,6 +139,11 @@ public: _data.Add(*str, str.Length()); return *this; } + StringBuilder& Append(const StringView& str) + { + _data.Add(*str, str.Length()); + return *this; + } // Append int to the string // @param val Value to append diff --git a/Source/Engine/Platform/Apple/ApplePlatform.cpp b/Source/Engine/Platform/Apple/ApplePlatform.cpp index c939c1af2..8a2e1d7ef 100644 --- a/Source/Engine/Platform/Apple/ApplePlatform.cpp +++ b/Source/Engine/Platform/Apple/ApplePlatform.cpp @@ -43,6 +43,7 @@ #include #if CRASH_LOG_ENABLE #include +#include #endif CPUInfo Cpu; @@ -502,20 +503,42 @@ Array ApplePlatform::GetStackFrames(int32 skipCount, { char** names = backtrace_symbols(callstack + skipCount, useCount); result.Resize(useCount); + Array parts; + int32 len; +#define COPY_STR(str, dst) \ + len = Math::Min(str.Length(), ARRAY_COUNT(frame.dst) - 1); \ + Platform::MemoryCopy(frame.dst, str.Get(), len); \ + frame.dst[len] = 0 for (int32 i = 0; i < useCount; i++) { - char* name = names[i]; + const StringAnsi name(names[i]); StackFrame& frame = result[i]; frame.ProgramCounter = callstack[skipCount + i]; frame.ModuleName[0] = 0; frame.FileName[0] = 0; frame.LineNumber = 0; - int32 nameLen = Math::Min(StringUtils::Length(name), ARRAY_COUNT(frame.FunctionName) - 1); - Platform::MemoryCopy(frame.FunctionName, name, nameLen); - frame.FunctionName[nameLen] = 0; - + + // Decode name + parts.Clear(); + name.Split(' ', parts); + if (parts.Count() == 6) + { + COPY_STR(parts[1], ModuleName); + const StringAnsiView toDemangle(parts[3]); + int status = 0; + char* demangled = __cxxabiv1::__cxa_demangle(*toDemangle, 0, 0, &status); + const StringAnsiView toCopy = demangled && status == 0 ? StringAnsiView(demangled) : StringAnsiView(toDemangle); + COPY_STR(toCopy, FunctionName); + if (demangled) + free(demangled); + } + else + { + COPY_STR(name, FunctionName); + } } free(names); +#undef COPY_STR } #endif return result; diff --git a/Source/Engine/Platform/Base/PlatformBase.cpp b/Source/Engine/Platform/Base/PlatformBase.cpp index d15bec61c..9a6b1b9dc 100644 --- a/Source/Engine/Platform/Base/PlatformBase.cpp +++ b/Source/Engine/Platform/Base/PlatformBase.cpp @@ -633,14 +633,21 @@ String PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* contex for (const auto& frame : stackFrames) { StringAsUTF16 functionName(frame.FunctionName); + const StringView functionNameStr(functionName.Get()); if (StringUtils::Length(frame.FileName) != 0) { StringAsUTF16 fileName(frame.FileName); - result.AppendFormat(TEXT(" at {0}() in {1}:line {2}\n"), functionName.Get(), fileName.Get(), frame.LineNumber); + result.Append(TEXT(" at ")).Append(functionNameStr); + if (!functionNameStr.EndsWith(')')) + result.Append(TEXT("()")); + result.AppendFormat(TEXT("in {0}:line {1}\n"),fileName.Get(), frame.LineNumber); } else if (StringUtils::Length(frame.FunctionName) != 0) { - result.AppendFormat(TEXT(" at {0}()\n"), functionName.Get()); + result.Append(TEXT(" at ")).Append(functionNameStr); + if (!functionNameStr.EndsWith(')')) + result.Append(TEXT("()")); + result.Append('\n'); } else {