diff --git a/Source/Engine/Platform/Web/WebPlatform.cpp b/Source/Engine/Platform/Web/WebPlatform.cpp index 3a820f5de..cbe4325ea 100644 --- a/Source/Engine/Platform/Web/WebPlatform.cpp +++ b/Source/Engine/Platform/Web/WebPlatform.cpp @@ -312,4 +312,50 @@ void* WebPlatform::GetProcAddress(void* handle, const char* symbol) return dlsym(handle, symbol); } +Array WebPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context) +{ + Array result; +#if CRASH_LOG_ENABLE + // Get callstack + char callstack[1024]; + emscripten_get_callstack(EM_LOG_JS_STACK, callstack, sizeof(callstack)); + + // Parse callstack + int32 pos = 0; + while (callstack[pos]) + { + StackFrame& frame = result.AddOne(); + frame.ProgramCounter = 0; + frame.ModuleName[0] = 0; + frame.FileName[0] = 0; + frame.LineNumber = 0; + + // Skip leading spaces + while (callstack[pos] == ' ') + pos++; + + // Skip 'at ' + pos += 3; + + // Read function name + int32 dst = 0; + while (callstack[pos] && callstack[pos] != '\n' && dst < ARRAY_COUNT(frame.FileName) - 1) + frame.FunctionName[dst++] = callstack[pos++]; + frame.FunctionName[dst] = 0; + + // Skip '\n' + if (callstack[pos]) + pos++; + } + + // Adjust frames range + skipCount += 2; // Skip this function and utility JS frames + while (skipCount-- && result.HasItems()) + result.RemoveAtKeepOrder(0); + if (result.Count() > maxDepth) + result.Resize(maxDepth); +#endif + return result; +} + #endif diff --git a/Source/Engine/Platform/Web/WebPlatform.h b/Source/Engine/Platform/Web/WebPlatform.h index bb9ec9d30..73b8588b8 100644 --- a/Source/Engine/Platform/Web/WebPlatform.h +++ b/Source/Engine/Platform/Web/WebPlatform.h @@ -114,6 +114,7 @@ public: static void* LoadLibrary(const Char* filename); static void FreeLibrary(void* handle); static void* GetProcAddress(void* handle, const char* symbol); + static Array GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr); }; #endif