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; }
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 *