Beispiel #1
0
static ssize_t coffeecatch_backtrace_signal(siginfo_t* si, void* sc, 
                                            backtrace_frame_t* frames,
                                            size_t ignore_depth,
                                            size_t max_depth) {
  void *const libcorkscrew = dlopen("libcorkscrew.so", RTLD_LAZY | RTLD_LOCAL);
  if (libcorkscrew != NULL) {
    t_unwind_backtrace_signal_arch unwind_backtrace_signal_arch 
      = (t_unwind_backtrace_signal_arch)
      dlsym(libcorkscrew, "unwind_backtrace_signal_arch");
    t_acquire_my_map_info_list acquire_my_map_info_list 
      = (t_acquire_my_map_info_list)
      dlsym(libcorkscrew, "acquire_my_map_info_list");
    t_release_my_map_info_list release_my_map_info_list 
      = (t_release_my_map_info_list)
      dlsym(libcorkscrew, "release_my_map_info_list");
    if (unwind_backtrace_signal_arch != NULL
        && acquire_my_map_info_list != NULL
        && release_my_map_info_list != NULL) {
      map_info_t*const info = acquire_my_map_info_list();
      const ssize_t size = 
        unwind_backtrace_signal_arch(si, sc, info, frames, ignore_depth,
                                     max_depth);
      release_my_map_info_list(info);
      return size;
    } else {
      DEBUG(print("symbols not founs in libcorkscrew.so\n"));
    }
    dlclose(libcorkscrew);
  } else {
    DEBUG(print("libcorkscrew.so could not be loaded\n"));
  }
  return -1;
}
static void unwind_backtrace_thread_signal_handler(int n __attribute__((unused)), siginfo_t* siginfo, void* sigcontext) {
    if (!android_atomic_acquire_cas(gettid(), STATE_DUMPING, &g_unwind_signal_state.tid_state)) {
        g_unwind_signal_state.returned_frames = unwind_backtrace_signal_arch(
                siginfo, sigcontext,
                g_unwind_signal_state.map_info_list,
                g_unwind_signal_state.backtrace,
                g_unwind_signal_state.ignore_depth,
                g_unwind_signal_state.max_depth);
        android_atomic_release_store(STATE_DONE, &g_unwind_signal_state.tid_state);
    } else {
        ALOGV("Received spurious SIGURG on thread %d that was intended for thread %d.",
                gettid(), android_atomic_acquire_load(&g_unwind_signal_state.tid_state));
    }
}
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
}