Android下堆栈信息打印

  • kernel层
    linux kernel中有堆栈打印的API接口dump_stack,直接调用即可;dump_stack的实现在kernel中的msm-3.18/lib/dump_stack.c
    和msm-3.18/kernel/printk/printk.c。
//在需要打印的堆栈信息的函数中加入即可
dump_stack();
  • c文件中打印
    c语言中的堆栈信息打印,需要自己实现接口,接口的实现如下代码,如下代码可以拿起来直接用
/*
如果android.mk中没有定义libdl,须加入;
LOCAL_SHARED_LIBRARIES += libdl
*/
#define MAX_DEPTH 31
//#define MAX_BACKTRACE_LINE_LENGTH 800
#define PATH "/system/lib/libcorkscrew.so"
#include "../../../../../../../../../../system/core/include/corkscrew/backtrace.h"
#include 
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 ){
        ALOGE("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);
    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);
        }
        ALOGE("%s", line);
    }
    free_backtrace_symbols(symbols, count);
    return result;
}
  • c++文件打印
// 添加头文件
#include 
void func(void)
{
……………………
CallStack stack(LOG_TAG);
……………………
}
  • java文件中打印
    java的调用比较简单,java库已经实现了堆栈,直接调用方法即可
   log.e(tag,"call java stack",new RuntimeException());

你可能感兴趣的:(学习)