Android 打印堆栈

1.Java中:
Log.e(“dump_test”,Log.getStackTraceString(new Throwable()));
 
2.C++中:
 <1>.test.cpp
  #include <utils/Log.h>
  #include <utils/CallStack.h>
  void dumping_callstack(){
   android::CallStack stack;
   //getpid()和gettid()效果一样
   //stack.update(2,getpid());
   //stack.update(2,gettid());
 
  stack.update();
  //输出到printf
  stack.dump(1);
  //输出到logcat
  stack.log("dump_test");
  //可以设置第2、3个参数
  //stack.log("Dumping Stack",ANDROID_LOG_ERROR ,"123 ");
}
 
void func1(){
  dumping_callstack();
}
 
void func2(){
 
  func1();
}
 
void func3(){
 
  func2();
}
int main(){
  ALOGE("main_test------------------>");
 
  func3();
}
 
 <2>.Android.mk
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
  LOCAL_SRC_FILES := test.cpp
  LOCAL_MODULE_TAGS := optional
  LOCAL_MODULE := test
  LOCAL_SHARED_LIBRARIES += libcutils libutils
  include $(BUILD_EXECUTABLE)
 
3.C中:
 <1>.创建callstack.cpp
   #include <utils/CallStack.h>
   extern "C" void dumping_callstack();
 
   void dumping_callstack(){
      android::CallStack stack;
      stack.update();
      stack.log(“dump_test“);
   }
  <2>.创建callstack.h
      void dumping_callstack();
  <3>.测试test.c
      #include "callstack.h"
 
      static ssize_t out_write(){
        dumping_callstack();
      }
  <4>.Anroid.mk中添加到编译选项:callstack.cpp及库
      LOCAL_SHARED_LIBRARIES := libcutils libutils
      LOCAL_SRC_FILES := callstack.cpp
 
4.Kernel中:
#include <asm/ptrace.h>
printk(KERN_ERR "dump_stack start: %s() %d \n",__FUNCTION__,__LINE__);  
 
dump_stack();
.......
printk(KERN_ERR "dump_stack stop: %s() %d \n",__FUNCTION__,__LINE__);  
根据dump stack的log位置加printk()。
 
测试:
# adb logcat | grep dump_test

打印C堆栈另一种方法
这里需要注意的是,为解决链接问题,最好使用dlopen方式,查找需要用到的接口再直接调用,这样会比较简单。如下为相关的实现代码,只需要在要打印的文件中插入此部分代码,然后调用getCallStack()即可,无需包含太多的头文件和修改Android.mk文件

#define MAX_DEPTH  31  
#define MAX_BACKTRACE_LINE_LENGTH   800  
#define PATH "/system/lib/libcorkscrew.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;  
  
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 : "<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,  
	                     ieldWidth, symbolName);  
	        }  
        } else {  
	        snprintf(line, MAX_BACKTRACE_LINE_LENGTH, "#%02d  pc %08x  %.*s",  
	                i, symbols[i].relative_pc, fieldWidth, mapName);  
	    }  
	  
        ALOGD("%s", line);  
	}  
	  
	free_backtrace_symbols(symbols, count);  
	  
    return result;  
}  

https://blog.csdn.net/q1183345443/article/details/82999385

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值