Skip to content

Commit 338a397

Browse files
committed
Android: added support for SystemStats::getStackBacktrace().
1 parent 150f7c5 commit 338a397

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

modules/juce_core/juce_core.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@
121121
#if JUCE_ANDROID
122122
#include <ifaddrs.h>
123123
#include <android/log.h>
124+
#include <unwind.h>
125+
#include <dlfcn.h>
126+
#include <cxxabi.h>
124127
#endif
125128

126129
#undef check

modules/juce_core/system/juce_SystemStats.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ String SystemStats::getStackBacktrace()
190190
{
191191
String result;
192192

193-
#if JUCE_ANDROID || JUCE_WASM
193+
#if JUCE_WASM
194194
jassertfalse; // sorry, not implemented yet!
195195

196196
#elif JUCE_WINDOWS
@@ -224,6 +224,63 @@ String SystemStats::getStackBacktrace()
224224
}
225225
}
226226

227+
#elif JUCE_ANDROID
228+
229+
struct AndroidBacktraceState
230+
{
231+
void** current;
232+
void** end;
233+
};
234+
235+
auto androidUnwindCallback = [] (_Unwind_Context* context, void* arg) -> _Unwind_Reason_Code
236+
{
237+
auto* state = (AndroidBacktraceState*) arg;
238+
if (auto pc = _Unwind_GetIP(context))
239+
{
240+
if (state->current == state->end)
241+
return _URC_END_OF_STACK;
242+
243+
*state->current++ = reinterpret_cast<void*> (pc);
244+
}
245+
246+
return _URC_NO_REASON;
247+
};
248+
249+
const int max = 100;
250+
void* buffer[max];
251+
252+
AndroidBacktraceState state;
253+
state.current = buffer;
254+
state.end = buffer + max;
255+
_Unwind_Backtrace (androidUnwindCallback, &state);
256+
257+
const auto count = (int) (state.current - buffer);
258+
259+
for (int i = 0; i < count; ++i)
260+
{
261+
const void* addr = buffer[i];
262+
result << i << " " << String::toHexString ((intptr_t) addr);
263+
264+
Dl_info info;
265+
if (dladdr (addr, &info) != 0 && info.dli_sname != nullptr)
266+
{
267+
const char* symbol = info.dli_sname;
268+
269+
int status = 0; // NB: '0' means success
270+
auto* demangled = abi::__cxa_demangle (symbol, nullptr, nullptr, &status);
271+
272+
if (demangled != nullptr && status == 0)
273+
result << demangled;
274+
else
275+
result << symbol;
276+
277+
if (demangled != nullptr)
278+
free (demangled);
279+
}
280+
281+
result << newLine;
282+
}
283+
227284
#else
228285
void* stack[128];
229286
auto frames = backtrace (stack, numElementsInArray (stack));

0 commit comments

Comments
 (0)