android打印线程回溯栈


/**
 * 获取JNI层调用栈
 * @param out
 * @return 0:success 1:failure
 */
int get_callstack(std::string &out, pid_t tid) {
    const int MAX_DEPTH = 31;
    const int MAX_BACKTRACE_LINE_LENGTH = 800;

    ssize_t i = 0;
    ssize_t result = 0;
    ssize_t count = 0;
    backtrace_frame_t mstack[MAX_DEPTH];
    backtrace_symbol_t symbols[MAX_DEPTH];

    static unwindFn unwind_backtrace = NULL;
    static unwindSymbFn get_bt_syms = NULL;
    static unwindSymbFreeFn free_bt_syms = NULL;

    if (tid == -1) {
        tid = gettid();
    }

    // open the so.
    static void *corkscrew_handle = NULL;
    if (corkscrew_handle == NULL) {
        // todo  For Android N, dlopen will fail
        corkscrew_handle = dlopen(vxStrEnc("/system/lib/libcorkscrew.so"), RTLD_NOW);
        unwind_backtrace = (unwindFn) dlsym(corkscrew_handle, vxStrEnc("unwind_backtrace_thread"));
        get_bt_syms = (unwindSymbFn) dlsym(corkscrew_handle, vxStrEnc("get_backtrace_symbols"));
        free_bt_syms = (unwindSymbFreeFn) dlsym(corkscrew_handle,
                                                vxStrEnc("free_backtrace_symbols"));
    }
    if (!corkscrew_handle || !unwind_backtrace || !get_bt_syms || !free_bt_syms) {
        // cannot get unwind info
        return -1;
    }

    // get the interface for unwind and symbol analyse
    count = unwind_backtrace(tid, mstack, 0, MAX_DEPTH); // -1 as error
    get_bt_syms(mstack, count, symbols);

    out = "";
    for (i = 0; i < count; i++) {
        char line[MAX_BACKTRACE_LINE_LENGTH];

        const char *mapname = symbols[i].map_name ? symbols[i].map_name : vxStrEnc("<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,
                         vxStrEnc("#%02d  pc %08x  %.*s (%.*s+%u)\n"),
                         i, symbols[i].relative_pc, fieldwidth, mapname,
                         fieldwidth, symbolname, pc_offset);
            } else {
                snprintf(line, MAX_BACKTRACE_LINE_LENGTH, vxStrEnc("#%02d  pc %08x  %.*s (%.*s)\n"),
                         i, symbols[i].relative_pc, fieldwidth, mapname,
                         fieldwidth, symbolname);
            }
        } else {
            snprintf(line, MAX_BACKTRACE_LINE_LENGTH, vxStrEnc("#%02d  pc %08x  %.*s\n"),
                     i, symbols[i].relative_pc, fieldwidth, mapname);
        }

        out += line;
    }
    if (count >= 0) {
        free_bt_syms(symbols, count);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值