Exemplo n.º 1
0
static void coffeecatch_backtrace_symbols(const backtrace_frame_t* backtrace,
                                          size_t frames,
                                          void (*fun)(void *arg,
                                          const backtrace_symbol_t *sym),
                                          void *arg) {
  void *const libcorkscrew = dlopen("libcorkscrew.so", RTLD_LAZY | RTLD_LOCAL);
  if (libcorkscrew != NULL) {
    t_get_backtrace_symbols get_backtrace_symbols 
      = (t_get_backtrace_symbols)
      dlsym(libcorkscrew, "get_backtrace_symbols");
    t_free_backtrace_symbols free_backtrace_symbols 
      = (t_free_backtrace_symbols)
      dlsym(libcorkscrew, "free_backtrace_symbols");
    if (get_backtrace_symbols != NULL
        && free_backtrace_symbols != NULL) {
      backtrace_symbol_t symbols[BACKTRACE_FRAMES_MAX];
      size_t i;
      if (frames > BACKTRACE_FRAMES_MAX) {
        frames = BACKTRACE_FRAMES_MAX;
      }
      get_backtrace_symbols(backtrace, frames, symbols);
      for(i = 0; i < frames; i++) {
        fun(arg, &symbols[i]);
      }
      free_backtrace_symbols(symbols, frames);
    }
    dlclose(libcorkscrew);
  }
}
void CallStack::dump(const char* logtag, const char* prefix) const {
    backtrace_symbol_t symbols[mCount];

    get_backtrace_symbols(mStack, mCount, symbols);
    for (size_t i = 0; i < mCount; i++) {
        char line[MAX_BACKTRACE_LINE_LENGTH];
        format_backtrace_line(i, &mStack[i], &symbols[i],
                line, MAX_BACKTRACE_LINE_LENGTH);
        ALOG(LOG_DEBUG, logtag, "%s%s",
                prefix ? prefix : "",
                line);
    }
    free_backtrace_symbols(symbols, mCount);
}
String8 CallStack::toString(const char* prefix) const {
    String8 str;
    backtrace_symbol_t symbols[mCount];

    get_backtrace_symbols(mStack, mCount, symbols);
    for (size_t i = 0; i < mCount; i++) {
        char line[MAX_BACKTRACE_LINE_LENGTH];
        format_backtrace_line(i, &mStack[i], &symbols[i],
                line, MAX_BACKTRACE_LINE_LENGTH);
        if (prefix) {
            str.append(prefix);
        }
        str.append(line);
        str.append("\n");
    }
    free_backtrace_symbols(symbols, mCount);
    return str;
}
Exemplo n.º 4
0
/*
 * Dump the native stack for the specified thread.
 */
void dvmDumpNativeStack(const DebugOutputTarget* target, pid_t tid)
{
#ifdef HAVE_ANDROID_OS
    const size_t MAX_DEPTH = 32;
    backtrace_frame_t backtrace[MAX_DEPTH];
    ssize_t frames = unwind_backtrace_thread(tid, backtrace, 0, MAX_DEPTH);
    if (frames > 0) {
        backtrace_symbol_t backtrace_symbols[MAX_DEPTH];
        get_backtrace_symbols(backtrace, frames, backtrace_symbols);

        for (size_t i = 0; i < size_t(frames); i++) {
            char line[MAX_BACKTRACE_LINE_LENGTH];
            format_backtrace_line(i, &backtrace[i], &backtrace_symbols[i],
                    line, MAX_BACKTRACE_LINE_LENGTH);
            dvmPrintDebugMessage(target, "  %s\n", line);
        }

        free_backtrace_symbols(backtrace_symbols, frames);
    }
#endif
}
Exemplo n.º 5
0
static int coffeecatch_backtrace_symbols(const backtrace_frame_t* backtrace,
                                         size_t frames,
                                         void (*fun)(void *arg,
                                         const backtrace_symbol_t *sym),
                                         void *arg) {
  int success = 0;
  void *const libcorkscrew = dlopen("libcorkscrew.so", RTLD_LAZY | RTLD_LOCAL);
  if (libcorkscrew != NULL) {
    t_get_backtrace_symbols get_backtrace_symbols 
      = (t_get_backtrace_symbols)
      dlsym(libcorkscrew, "get_backtrace_symbols");
    t_free_backtrace_symbols free_backtrace_symbols 
      = (t_free_backtrace_symbols)
      dlsym(libcorkscrew, "free_backtrace_symbols");
    if (get_backtrace_symbols != NULL
        && free_backtrace_symbols != NULL) {
      backtrace_symbol_t symbols[BACKTRACE_FRAMES_MAX];
      size_t i;
      if (frames > BACKTRACE_FRAMES_MAX) {
        frames = BACKTRACE_FRAMES_MAX;
      }
      get_backtrace_symbols(backtrace, frames, symbols);
      for(i = 0; i < frames; i++) {
        fun(arg, &symbols[i]);
      }
      free_backtrace_symbols(symbols, frames);
      success = 1;
    } else {
      DEBUG(print("symbols not found in libcorkscrew.so\n"));
    }
    dlclose(libcorkscrew);
  } else {
    DEBUG(print("libcorkscrew.so could not be loaded\n"));
  }
  return success;
}
static char *
mono_extension_handle_native_sigsegv_libcorkscrew (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
{
#if defined (__arm__) || defined (__i386__)
    char *dl_err;

    get_backtrace_symbols_t get_backtrace_symbols;
    free_backtrace_symbols_t free_backtrace_symbols;
    unwind_backtrace_signal_arch_t unwind_backtrace_signal_arch;
    acquire_my_map_info_list_t acquire_my_map_info_list;
    release_my_map_info_list_t release_my_map_info_list;

    backtrace_frame_t frames [FRAMES_TO_UNWIND];
    backtrace_symbol_t symbols [FRAMES_TO_UNWIND];

    map_info_t *map_info;
    ssize_t frames_unwound;
    size_t i;

    MonoDl *dl = mono_dl_open ("libcorkscrew.so", MONO_DL_LAZY, &dl_err);

    if (!dl)
        return dl_err;

    LOAD_SYM (dl, dl_err, get_backtrace_symbols, get_backtrace_symbols);
    LOAD_SYM (dl, dl_err, free_backtrace_symbols, free_backtrace_symbols);
    LOAD_SYM (dl, dl_err, unwind_backtrace_signal_arch, unwind_backtrace_signal_arch);
    LOAD_SYM (dl, dl_err, acquire_my_map_info_list, acquire_my_map_info_list);
    LOAD_SYM (dl, dl_err, release_my_map_info_list, release_my_map_info_list);

    map_info = acquire_my_map_info_list ();
    frames_unwound = unwind_backtrace_signal_arch (info, ctx, map_info, frames, 0, FRAMES_TO_UNWIND);
    release_my_map_info_list (map_info);

    if (frames_unwound == -1) {
        mono_dl_close (dl);

        return g_strdup ("unwind_backtrace_signal_arch () returned -1");
    }

    get_backtrace_symbols (frames, frames_unwound, symbols);

    for (i = 0; i < frames_unwound; i++) {
        backtrace_frame_t *frame = frames + i;
        backtrace_symbol_t *symbol = symbols + i;

        const char *name = symbol->demangled_name ? symbol->demangled_name : (symbol->symbol_name ? symbol->symbol_name : "???");
        uintptr_t off = symbol->relative_pc - symbol->relative_symbol_addr;
        uintptr_t ip = frame->absolute_pc;

        mono_runtime_printf_err ("  at %s+%zu [0x%zx]", name, off, ip);
    }

    free_backtrace_symbols (symbols, frames_unwound);

    mono_dl_close (dl);

    return NULL;
#else
    return g_strdup ("libcorkscrew is only supported on 32-bit ARM/x86");
#endif
}