@@ -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