__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);
    }
  }
}
Ejemplo n.º 2
0
__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);
    }
  }
}