android native 调试 打印调用栈
16lz
2021-01-23
在调试 android 某些应用时,需要打印调用栈, 但是高版本的5.0 以上已经去掉了libcorkscrew.so 和 libcutils.so 两个库,改用其他的google 库文件,但是可以使用andorid 4.4 , 4.3 系统使用。使用时可以直接调用 getCallStack()该方法即可。
android 6.0 可用 typedef int (*Unw_BackTrace_Func)(void**, int);void print_backtrace() { static Unw_BackTrace_Func unw_backtrace = NULL; if (!unw_backtrace) { void *hanle = dlopen("libunwind.so", RTLD_NOW); unw_backtrace = (Unw_BackTrace_Func)dlsym(hanle, "unw_backtrace"); } void *buffer[32] = { 0 }; int n = unw_backtrace((void**)&buffer, 32); for(int i = 1; i < n; i++) { const char *file = "\t\t\t\t"; const char *symbol = "\t\t\t\t"; Dl_info info; if (dladdr(buffer[i], &info)) { if (info.dli_sname) { symbol = info.dli_sname; } if (info.dli_fname) { file = info.dli_fname; } } __android_log_print(ANDROID_LOG_INFO, TAG, "uuu:#%02d: %p,%s,%s", i, buffer[i], symbol, file); }}
/********************************hh********************************/#include
#include #include #include #include #define MAX_DEPTH 66#define MAX_BACKTRACE_LINE_LENGTH 800#define PATH "/system/lib/libcorkscrew.so"#define PATH_uu "/system/lib/libcutils.so"typedef ssize_t (*unwindFn)(backtrace_frame_t *, size_t, size_t);typedef void (*unwindSymbFn)(const backtrace_frame_t *, size_t, backtrace_symbol_t *);typedef void (*unwindSymbFreeFn)(backtrace_symbol_t *, size_t);static void *gHandle = NULL;int getCallStack(void) { ssize_t i = 0; ssize_t result = 0; ssize_t count; backtrace_frame_t mStack[MAX_DEPTH]; backtrace_symbol_t symbols[MAX_DEPTH]; unwindFn unwind_backtrace = NULL; unwindSymbFn get_backtrace_symbols = NULL; unwindSymbFreeFn free_backtrace_symbols = NULL; if (gHandle == NULL) { gHandle = dlopen(PATH_uu, RTLD_NOW); } // open the so. if (gHandle == NULL) { gHandle = dlopen(PATH, RTLD_NOW); } // get the interface for unwind and symbol analyse if (gHandle != NULL) { unwind_backtrace = (unwindFn) dlsym(gHandle, "unwind_backtrace"); } else{ LOGD("tian>>>dleerr55>%s", dlerror()); } if (gHandle != NULL) { get_backtrace_symbols = (unwindSymbFn) dlsym(gHandle, "get_backtrace_symbols"); } else{ LOGD("tian>>>dleerr444>%s", dlerror()); } if (gHandle != NULL) { free_backtrace_symbols = (unwindSymbFreeFn) dlsym(gHandle, "free_backtrace_symbols"); } else{ LOGD("tian>>>dlee6666rr>%s", dlerror()); } if (!gHandle || !unwind_backtrace || !get_backtrace_symbols || !free_backtrace_symbols) { LOGD("tian Error! cannot get unwind info: handle:%p %p %p %p", gHandle, unwind_backtrace, get_backtrace_symbols, free_backtrace_symbols); return result; } count = unwind_backtrace(mStack, 1, MAX_DEPTH); LOGD("tian>>>dleecount>%d", count); get_backtrace_symbols(mStack, count, symbols); for (i = 0; i < count; i++) { char line[MAX_BACKTRACE_LINE_LENGTH]; const char *mapName = symbols[i].map_name ? symbols[i].map_name : "
"; const char *symbolName = symbols[i].demangled_name ? symbols[i].demangled_name : symbols[i].symbol_name; size_t fieldWidth = (MAX_BACKTRACE_LINE_LENGTH - 80) / 2; if (symbolName) { uint32_t pc_offset = symbols[i].relative_pc - symbols[i].relative_symbol_addr; if (pc_offset) { snprintf(line, MAX_BACKTRACE_LINE_LENGTH, "#%02d pc %08x %.*s (%.*s+%u)", i, symbols[i].relative_pc, fieldWidth, mapName, fieldWidth, symbolName, pc_offset); } else { snprintf(line, MAX_BACKTRACE_LINE_LENGTH, "#%02d pc %08x %.*s (%.*s)", i, symbols[i].relative_pc, fieldWidth, mapName, fieldWidth, symbolName); } } else { snprintf(line, MAX_BACKTRACE_LINE_LENGTH, "#%02d pc %08x %.*s", i, symbols[i].relative_pc, fieldWidth, mapName); } LOGD("tian>>>555>%s", line); } free_backtrace_symbols(symbols, count); return result;}
5.1 手机使用方法。
typedef int (*Unw_BackTrace_Func)(void**, int);void print_backtrace() { static Unw_BackTrace_Func unw_backtrace = NULL; if (!unw_backtrace) { void *hanle = dlopen("libunwind.so", RTLD_NOW); unw_backtrace = (Unw_BackTrace_Func)dlsym(hanle, "unw_backtrace"); } void *buffer[32] = { 0 }; int n = unw_backtrace((void**)&buffer, 32); for(int i = 1; i < n; i++) { const char *file = "\t\t\t\t"; const char *symbol = "\t\t\t\t"; Dl_info info; if (dladdr(buffer[i], &info)) { if (info.dli_sname) { symbol = info.dli_sname; } if (info.dli_fname) { file = info.dli_fname; } } LOGI("#%02d: %p \t %s \t %s", i, buffer[i], symbol, file); }}
更多相关文章
- Android Gallery控件使用方法详解
- Android 开发获取通知栏权限时会出现两个应用图标
- 【转】Android-Action Bar使用方法
- Git,SVN使用方法杂记(更新中)
- Android ActionBar使用方法(二)
- Android 拼接两个图片
- Android自定义属性 及 TypedArray的使用方法
- [置顶] Android之ContextMenu的使用方法以及与OptionMenu的区别