Add separate Platform::GetStackTrace and Platform::GetStackFrames

This commit is contained in:
Wojtek Figat
2021-02-26 13:58:02 +01:00
parent e1387e92a3
commit a45b71617d
4 changed files with 42 additions and 9 deletions

View File

@@ -202,11 +202,11 @@ void PlatformBase::Fatal(const Char* msg, void* context)
LOG(Error, "");
// Log stack trace
const auto stackTrace = Platform::GetStackTrace(context ? 0 : 1, 60, context);
if (stackTrace.HasItems())
const auto stackFrames = Platform::GetStackFrames(context ? 0 : 1, 60, context);
if (stackFrames.HasItems())
{
LOG(Error, "Stack trace:");
for (const auto& frame : stackTrace)
for (const auto& frame : stackFrames)
{
char chr = 0;
int32 num = StringUtils::Length(frame.ModuleName);
@@ -217,11 +217,11 @@ void PlatformBase::Fatal(const Char* msg, void* context)
if (StringUtils::Length(frame.FileName) != 0)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FileName)> fileName(frame.FileName);
LOG(Error, " at {0}!{1} in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber);
LOG(Error, " at {0}!{1}() in {2}:line {3}", moduleName.Get(), functionName.Get(), fileName.Get(), frame.LineNumber);
}
else if (StringUtils::Length(frame.FunctionName) != 0)
{
LOG(Error, " at {0}::{1}", moduleName.Get(), functionName.Get());
LOG(Error, " at {0}!{1}()", moduleName.Get(), functionName.Get());
}
else if (StringUtils::Length(frame.ModuleName) != 0)
{
@@ -483,11 +483,35 @@ int32 PlatformBase::RunProcess(const StringView& cmdLine, const StringView& work
return -1;
}
Array<PlatformBase::StackFrame> PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
Array<PlatformBase::StackFrame> PlatformBase::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
{
return Array<StackFrame>();
}
String PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
{
StringBuilder result;
Array<StackFrame> stackFrames = Platform::GetStackFrames(skipCount, maxDepth, context);
for (const auto& frame : stackFrames)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FunctionName)> functionName(frame.FunctionName);
if (StringUtils::Length(frame.FileName) != 0)
{
StringAsUTF16<ARRAY_COUNT(StackFrame::FileName)> fileName(frame.FileName);
result.AppendFormat(TEXT(" at {0}() in {1}:line {2}\n"), functionName.Get(), fileName.Get(), frame.LineNumber);
}
else if (StringUtils::Length(frame.FunctionName) != 0)
{
result.AppendFormat(TEXT(" at {0}()\n"), functionName.Get());
}
else
{
result.AppendFormat(TEXT(" at 0x{0:x}\n"), (uint64)frame.ProgramCounter);
}
}
return result.ToString();
}
void PlatformBase::CollectCrashData(const String& crashDataFolder, void* context)
{
}

View File

@@ -804,7 +804,16 @@ public:
/// <param name="maxDepth">The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception.</param>
/// <param name="context">The platform-dependent context for the stack trace collecting (eg. platform exception info).</param>
/// <returns>The collected stack trace frames. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build).</returns>
static Array<StackFrame, HeapAllocation> GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
/// <summary>
/// Gets current native stack trace information as string.
/// </summary>
/// <param name="skipCount">The amount of stack frames to skip from the beginning. Can be used to skip the callee function from the trace (eg. in crash handler).</param>
/// <param name="maxDepth">The maximum depth of the stack to collect. Can be used to prevent too long stack traces in case of stack overflow exception.</param>
/// <param name="context">The platform-dependent context for the stack trace collecting (eg. platform exception info).</param>
/// <returns>The collected stack trace printed into string. Empty if not supported (eg. platform not implements this feature or not supported in the distributed build).</returns>
static String GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
// Crash dump data handling
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);

View File

@@ -1107,7 +1107,7 @@ void* WindowsPlatform::LoadLibrary(const Char* filename)
return handle;
}
Array<PlatformBase::StackFrame> WindowsPlatform::GetStackTrace(int32 skipCount, int32 maxDepth, void* context)
Array<PlatformBase::StackFrame> WindowsPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
{
Array<StackFrame> result;
#if CRASH_LOG_ENABLE

View File

@@ -82,7 +82,7 @@ public:
static int32 RunProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String>& environment, bool hiddenWindow = true);
static Window* CreateWindow(const CreateWindowSettings& settings);
static void* LoadLibrary(const Char* filename);
static Array<StackFrame, HeapAllocation> GetStackTrace(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
#if CRASH_LOG_ENABLE
static void CollectCrashData(const String& crashDataFolder, void* context = nullptr);
#endif