Add GetStackFrames on Android
This commit is contained in:
@@ -51,6 +51,33 @@
|
|||||||
#include <android/window.h>
|
#include <android/window.h>
|
||||||
#include <android/versioning.h>
|
#include <android/versioning.h>
|
||||||
|
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
|
||||||
|
#include <unwind.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
struct AndroidBacktraceState
|
||||||
|
{
|
||||||
|
void** Current;
|
||||||
|
void** End;
|
||||||
|
};
|
||||||
|
|
||||||
|
_Unwind_Reason_Code AndroidUnwindCallback(struct _Unwind_Context* context, void* arg)
|
||||||
|
{
|
||||||
|
AndroidBacktraceState* state = (AndroidBacktraceState*)arg;
|
||||||
|
uintptr_t pc = _Unwind_GetIP(context);
|
||||||
|
if (pc)
|
||||||
|
{
|
||||||
|
if (state->Current == state->End)
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
else
|
||||||
|
*state->Current++ = reinterpret_cast<void*>(pc);
|
||||||
|
}
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct AndroidKeyEventType
|
struct AndroidKeyEventType
|
||||||
{
|
{
|
||||||
uint32_t KeyCode;
|
uint32_t KeyCode;
|
||||||
@@ -1066,4 +1093,45 @@ void* AndroidPlatform::GetProcAddress(void* handle, const char* symbol)
|
|||||||
return dlsym(handle, symbol);
|
return dlsym(handle, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<AndroidPlatform::StackFrame> AndroidPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
|
||||||
|
{
|
||||||
|
Array<StackFrame> result;
|
||||||
|
#if CRASH_LOG_ENABLE
|
||||||
|
// Reference: https://stackoverflow.com/questions/8115192/android-ndk-getting-the-backtrace
|
||||||
|
void* callstack[120];
|
||||||
|
skipCount = Math::Min<int32>(skipCount, ARRAY_COUNT(callstack));
|
||||||
|
int32 maxCount = Math::Min<int32>(ARRAY_COUNT(callstack), skipCount + maxDepth);
|
||||||
|
AndroidBacktraceState state;
|
||||||
|
state.Current = callstack;
|
||||||
|
state.End = callstack + maxCount;
|
||||||
|
_Unwind_Backtrace(AndroidUnwindCallback, &state);
|
||||||
|
int32 count = (int32)(state.Current - callstack);
|
||||||
|
int32 useCount = count - skipCount;
|
||||||
|
if (useCount > 0)
|
||||||
|
{
|
||||||
|
result.Resize(useCount);
|
||||||
|
for (int32 i = 0; i < useCount; i++)
|
||||||
|
{
|
||||||
|
StackFrame& frame = result[i];
|
||||||
|
frame.ProgramCounter = callstack[skipCount + i];
|
||||||
|
frame.ModuleName[0] = 0;
|
||||||
|
frame.FileName[0] = 0;
|
||||||
|
frame.LineNumber = 0;
|
||||||
|
Dl_info info;
|
||||||
|
const char* symbol = "";
|
||||||
|
if (dladdr(frame.ProgramCounter, &info) && info.dli_sname)
|
||||||
|
symbol = info.dli_sname;
|
||||||
|
int status = 0;
|
||||||
|
char* demangled = __cxxabiv1::__cxa_demangle(symbol, 0, 0, &status);
|
||||||
|
int32 nameLen = Math::Min<int32>(StringUtils::Length(demangled), ARRAY_COUNT(frame.FunctionName) - 1);
|
||||||
|
Platform::MemoryCopy(frame.FunctionName, demangled, nameLen);
|
||||||
|
frame.FunctionName[nameLen] = 0;
|
||||||
|
if (demangled)
|
||||||
|
free(demangled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ public:
|
|||||||
static void* LoadLibrary(const Char* filename);
|
static void* LoadLibrary(const Char* filename);
|
||||||
static void FreeLibrary(void* handle);
|
static void FreeLibrary(void* handle);
|
||||||
static void* GetProcAddress(void* handle, const char* symbol);
|
static void* GetProcAddress(void* handle, const char* symbol);
|
||||||
|
static Array<StackFrame, HeapAllocation> GetStackFrames(int32 skipCount = 0, int32 maxDepth = 60, void* context = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user