Add GetStackFrames on Android
This commit is contained in:
@@ -51,6 +51,33 @@
|
||||
#include <android/window.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
|
||||
{
|
||||
uint32_t KeyCode;
|
||||
@@ -1066,4 +1093,45 @@ void* AndroidPlatform::GetProcAddress(void* handle, const char* 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
|
||||
|
||||
Reference in New Issue
Block a user