在调试 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);
}
}