Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android NDK: getting the backtrace

I'm developing the native application that works with Android via the NDK. I need to call the backtrace() function when there is a crash. The problem is that there is no <execinfo.h> for the NDK.

Is there any other way to get that back trace?

like image 251
givi Avatar asked Nov 13 '11 22:11

givi


1 Answers

Android have no backtrace(), but unwind.h is here to serve. Symbolization is possible via dladdr().

The following code is my simple implementation of backtrace (with no demangling):

#include <iostream> #include <iomanip>  #include <unwind.h> #include <dlfcn.h>  namespace {  struct BacktraceState {     void** current;     void** end; };  static _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg) {     BacktraceState* state = static_cast<BacktraceState*>(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; }  }  size_t captureBacktrace(void** buffer, size_t max) {     BacktraceState state = {buffer, buffer + max};     _Unwind_Backtrace(unwindCallback, &state);      return state.current - buffer; }  void dumpBacktrace(std::ostream& os, void** buffer, size_t count) {     for (size_t idx = 0; idx < count; ++idx) {         const void* addr = buffer[idx];         const char* symbol = "";          Dl_info info;         if (dladdr(addr, &info) && info.dli_sname) {             symbol = info.dli_sname;         }          os << "  #" << std::setw(2) << idx << ": " << addr << "  " << symbol << "\n";     } } 

It may be used for backtracing into LogCat like

#include <sstream> #include <android/log.h>  void backtraceToLogcat() {     const size_t max = 30;     void* buffer[max];     std::ostringstream oss;      dumpBacktrace(oss, buffer, captureBacktrace(buffer, max));      __android_log_print(ANDROID_LOG_INFO, "app_name", "%s", oss.str().c_str()); } 
like image 55
Eugene Shapovalov Avatar answered Sep 28 '22 17:09

Eugene Shapovalov