__LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) { uintptr_t self_bt[16]; if (frames == NULL) { frame_count = get_backtrace(self_bt, 16); frames = self_bt; } __libc_format_log(ANDROID_LOG_ERROR, "libc", "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); for (size_t i = 0 ; i < frame_count; ++i) { uintptr_t offset = 0; const char* symbol = NULL; Dl_info info; if (dladdr((void*) frames[i], &info) != 0) { offset = reinterpret_cast<uintptr_t>(info.dli_saddr); symbol = info.dli_sname; } uintptr_t rel_pc; const mapinfo_t* mi = (gMapInfo != NULL) ? mapinfo_find(gMapInfo, frames[i], &rel_pc) : NULL; const char* soname = (mi != NULL) ? mi->name : info.dli_fname; if (soname == NULL) { soname = "<unknown>"; } if (symbol != NULL) { // TODO: we might need a flag to say whether it's safe to allocate (demangling allocates). char* demangled_symbol = demangle(symbol); const char* best_name = (demangled_symbol != NULL) ? demangled_symbol : symbol; __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02zd pc %0*" PRIxPTR " %s (%s+%" PRIuPTR ")", i, static_cast<int>(2 * sizeof(void*)), rel_pc, soname, best_name, frames[i] - offset); free(demangled_symbol); } else { __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02zd pc %0*" PRIxPTR " %s", i, static_cast<int>(2 * sizeof(void*)), rel_pc, soname); } } }
__LIBC_HIDDEN__ void log_backtrace(uintptr_t* frames, size_t frame_count) { ScopedDisableDebugCalls disable; uintptr_t self_bt[16]; if (frames == NULL) { frame_count = get_backtrace(self_bt, 16); frames = self_bt; } __libc_format_log(ANDROID_LOG_ERROR, "libc", "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); for (size_t i = 0 ; i < frame_count; ++i) { uintptr_t offset = 0; const char* symbol = NULL; Dl_info info; if (dladdr((void*) frames[i], &info) != 0) { offset = reinterpret_cast<uintptr_t>(info.dli_saddr); symbol = info.dli_sname; } uintptr_t rel_pc = offset; const mapinfo_t* mi = (g_map_info != NULL) ? mapinfo_find(g_map_info, frames[i], &rel_pc) : NULL; const char* soname = (mi != NULL) ? mi->name : info.dli_fname; if (soname == NULL) { soname = "<unknown>"; } if (symbol != NULL) { char* demangled_symbol = __cxa_demangle(symbol, NULL, NULL, NULL); const char* best_name = (demangled_symbol != NULL) ? demangled_symbol : symbol; __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02zd pc %" PAD_PTR " %s (%s+%" PRIuPTR ")", i, rel_pc, soname, best_name, frames[i] - offset); free(demangled_symbol); } else { __libc_format_log(ANDROID_LOG_ERROR, "libc", " #%02zd pc %" PAD_PTR " %s", i, rel_pc, soname); } } }