diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp index eb58eec26a..303c6e8719 100644 --- a/modules/juce_core/juce_core.cpp +++ b/modules/juce_core/juce_core.cpp @@ -121,6 +121,9 @@ #if JUCE_ANDROID #include #include + #include + #include + #include #endif #undef check diff --git a/modules/juce_core/system/juce_SystemStats.cpp b/modules/juce_core/system/juce_SystemStats.cpp index 6dafa07185..534a17de3f 100644 --- a/modules/juce_core/system/juce_SystemStats.cpp +++ b/modules/juce_core/system/juce_SystemStats.cpp @@ -190,7 +190,7 @@ String SystemStats::getStackBacktrace() { String result; - #if JUCE_ANDROID || JUCE_WASM + #if JUCE_WASM jassertfalse; // sorry, not implemented yet! #elif JUCE_WINDOWS @@ -224,6 +224,63 @@ String SystemStats::getStackBacktrace() } } + #elif JUCE_ANDROID + + struct AndroidBacktraceState + { + void** current; + void** end; + }; + + auto androidUnwindCallback = [] (_Unwind_Context* context, void* arg) -> _Unwind_Reason_Code + { + auto* state = (AndroidBacktraceState*) arg; + if (auto pc = _Unwind_GetIP(context)) + { + if (state->current == state->end) + return _URC_END_OF_STACK; + + *state->current++ = reinterpret_cast (pc); + } + + return _URC_NO_REASON; + }; + + const int max = 100; + void* buffer[max]; + + AndroidBacktraceState state; + state.current = buffer; + state.end = buffer + max; + _Unwind_Backtrace (androidUnwindCallback, &state); + + const auto count = (int) (state.current - buffer); + + for (int i = 0; i < count; ++i) + { + const void* addr = buffer[i]; + result << i << " " << String::toHexString ((intptr_t) addr); + + Dl_info info; + if (dladdr (addr, &info) != 0 && info.dli_sname != nullptr) + { + const char* symbol = info.dli_sname; + + int status = 0; // NB: '0' means success + auto* demangled = abi::__cxa_demangle (symbol, nullptr, nullptr, &status); + + if (demangled != nullptr && status == 0) + result << demangled; + else + result << symbol; + + if (demangled != nullptr) + free (demangled); + } + + result << newLine; + } + #else void* stack[128]; auto frames = backtrace (stack, numElementsInArray (stack));