Android下 c语言 打印调试堆栈方法(一)

参考文章    http://blog.csdn.net/freshui/article/details/9456889

文章末尾提到的直接插入代码段有点错误,一开始还是需要导入一个头文件,具体解决为如下:

#define MAX_DEPTH  31
#define MAX_BACKTRACE_LINE_LENGTH  800
#define PATH "/system/lib/libcorkscrew.so"


//https://raw.githubusercontent.com/zhuowei/libcorkscrew-ndk/master/corkscrew/backtrace.h
typedef struct {
    uintptr_t absolute_pc;     /* absolute PC offset */
    uintptr_t stack_top;       /* top of stack for this frame */
    size_t stack_size;         /* size of this stack frame */
} backtrace_frame_t;


typedef struct {
    uintptr_t relative_pc;       /* relative frame PC offset from the start of the library,or the absolute PC if the library is unknown */
    uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of thelibrary or 0 if the library is unknown */
    char* map_name;              /* executable or library name, or NULL if unknown */
    char* symbol_name;           /* symbol name, or NULL if unknown */
    char* demangled_name;        /* demangled symbol name, or NULL if unknown */
} backtrace_symbol_t;



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;

static 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;

    // 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");
    
    if(gHandle != NULL) get_backtrace_symbols = (unwindSymbFn)dlsym(gHandle, "get_backtrace_symbols");
    
    if(gHandle != NULL) free_backtrace_symbols = (unwindSymbFreeFn)dlsym(gHandle, "free_backtrace_symbols");
    

    if(!gHandle ||!unwind_backtrace ||!get_backtrace_symbols || !free_backtrace_symbols  )
    {
        MY_LOG_INFO("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,0, MAX_DEPTH);  //change 0 to other will return -1
    if (count == -1)
    {
        MY_LOG_INFO("Error! %d",count);
        return result;
    }
    
    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);
               }

        MY_LOG_INFO("%s", line);
    }

    free_backtrace_symbols(symbols, count);

    return result;
}


这里有两个问题:

1、代码标红色处,如果将0改为其他值,函数就会返回-1报错,这是为什么?

2、仍旧是该处,如果改为0能成功运行,但是只会打印一行log?这又是为什么?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值