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?
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()); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With