static char *
mono_extension_handle_native_sigsegv_libunwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info)
{
    char *dl_err;
    int unw_err;

    unw_init_local_t unw_init_local_fn;
    unw_get_reg_t unw_get_reg_fn;
    unw_get_proc_name_t unw_get_proc_name_fn;
    unw_step_t unw_step_fn;

    unw_cursor_t cursor;

    size_t frames = 0;

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

    if (!dl)
        return dl_err;

    LOAD_SYM (dl, dl_err, UNW_OBJ (init_local), unw_init_local_fn);
    LOAD_SYM (dl, dl_err, UNW_OBJ (get_reg), unw_get_reg_fn);
    LOAD_SYM (dl, dl_err, UNW_OBJ (get_proc_name), unw_get_proc_name_fn);
    LOAD_SYM (dl, dl_err, UNW_OBJ (step), unw_step_fn);

    if ((unw_err = unw_init_local_fn (&cursor, ctx))) {
        mono_dl_close (dl);

        return g_strdup_printf ("unw_init_local () returned %d", unw_err);
    }

    do {
        int reg_err;

        unw_word_t ip, off;
        char name [FUNC_NAME_LENGTH];

        if ((reg_err = unw_get_reg_fn (&cursor, UNW_REG_IP, &ip))) {
            mono_runtime_printf_err ("unw_get_reg (UNW_REG_IP) returned %d", reg_err);
            break;
        }

        reg_err = unw_get_proc_name_fn (&cursor, name, FUNC_NAME_LENGTH, &off);

        if (reg_err == -UNW_ENOINFO)
            strcpy (name, "???");

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

        unw_err = unw_step_fn (&cursor);
        frames++;
    } while (unw_err > 0 && frames < FRAMES_TO_UNWIND);

    if (unw_err < 0)
        mono_runtime_printf_err ("unw_step () returned %d", unw_err);

    mono_dl_close (dl);

    return NULL;
}
Esempio n. 2
0
  CORE_ADDR base;
  CORE_ADDR func_addr;
  unw_cursor_t cursor;
};

/* We need to qualify the function names with a platform-specific prefix to match 
   the names used by the libunwind library.  The UNW_OBJ macro is provided by the
   libunwind.h header file.  */
#define STRINGIFY2(name)	#name
#define STRINGIFY(name)		STRINGIFY2(name)

#ifndef LIBUNWIND_SO
#define LIBUNWIND_SO "libunwind-" STRINGIFY(UNW_TARGET) ".so"
#endif

static char *get_reg_name = STRINGIFY(UNW_OBJ(get_reg));
static char *get_fpreg_name = STRINGIFY(UNW_OBJ(get_fpreg));
static char *get_saveloc_name = STRINGIFY(UNW_OBJ(get_save_loc));
static char *step_name = STRINGIFY(UNW_OBJ(step));
static char *init_remote_name = STRINGIFY(UNW_OBJ(init_remote));
static char *create_addr_space_name = STRINGIFY(UNW_OBJ(create_addr_space));
static char *search_unwind_table_name = STRINGIFY(UNW_OBJ(search_unwind_table));
static char *find_dyn_list_name = STRINGIFY(UNW_OBJ(find_dyn_list));

static struct libunwind_descr *
libunwind_descr (struct gdbarch *gdbarch)
{
  return gdbarch_data (gdbarch, libunwind_descr_handle);
}

static void *