android native 调试 打印调用栈
Posted 明风的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android native 调试 打印调用栈相关的知识,希望对你有一定的参考价值。
在调试 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 <utils/CallStack.h> #include <utils/Trace.h> #include <dlfcn.h> #include <unwind.h> #include <dlfcn.h>
#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 : "<unknown>"; 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 native 调试 打印调用栈的主要内容,如果未能解决你的问题,请参考以下文章
利用Xposed Hook打印Java函数调用堆栈信息的几种方法
无法将 Android 模拟器连接到 React Native 调试器