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