Android打印堆栈

      • java打印堆栈
          • 方法一:异常对象打印堆栈
          • 方法二:Log打印获取异常的堆栈并打印
      • C++\C打印堆栈
          • 方法一:linux函数
          • 方法二:使用Android工具方法
      • kernel打印堆栈
      • 注意

java打印堆栈

方法一:异常对象打印堆栈
Exception e = new Exception("this is a log");e.printStackTrace();
方法二:Log打印获取异常的堆栈并打印
Log.e(“dump_test”,Log.getStackTraceString(new Throwable()));

C++\C打印堆栈

方法一:linux函数

函数介绍
头文件:

#include 

函数方法:

// 获取当前的调用栈信息,结果存储在buffer中,返回值为栈的深度,参数size限制栈的最大深度,即最大取size步的栈信息。int backtrace(void **buffer, int size);// 把backtrace获取的栈信息转化为字符串,以字符指针数组的形式返回,参数size限定转换的深度,一般用backtrace调用的返回值。char **backtrace_symbols(void *const *buffer, int size);// 它的功能和backtrace_symbols差不多,只不过它不把转换结果返回给调用方,而是写入fd指定的文件描述符。void backtrace_symbols_fd(void *const *buffer, int size, int fd);

编译选项

 -rdynamic  -g 

gcc编译时加上-rdynamic和-g编译选项,就可以看到被调用的函数和地址,如下

stackstrace begin:./test3(_Z16print_stacktracev+0x26) [0x4008e5]./test3(_Z4fun1v+0x13) [0x4008a7]./test3(_Z4fun2v+0x9) [0x4008b2]./test3(_Z4fun3v+0x9) [0x4008bd]./test3(main+0x9) [0x40088d]/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xff) [0x7fa9558c1eff]./test3() [0x4007c9]

堆栈转换
若有一个函数有多个地方被调用,可以使用addr2line,把调用地址转换为行数

// addr2line -aCfe lib addr$ addr2line -aCfe 0x4008a7 test30x00000000004008a7fun1()/home/wuzesheng/work/test/test.cc:20

Android使用编译选项
在Android中,编译脚本是Android源码中已经写好的,可以在Android.mk中以下面方式添加编译选项

LOCAL_CFLAGS += -rdynamic -g

linux下使用编译选项
非Android编译,使用如下命令

gcc test.cc -rdynamic -g -o test3

示例:

#include        #include        #include        #include        void       myfunc3(void)       {           int j, nptrs;       #define SIZE 100           void *buffer[100];           char **strings;           nptrs = backtrace(buffer, SIZE);           printf("backtrace() returned %d addresses\n", nptrs);           /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)              would produce similar output to the following: */           strings = backtrace_symbols(buffer, nptrs);           if (strings == NULL) {               perror("backtrace_symbols");               exit(EXIT_FAILURE);           }           for (j = 0; j < nptrs; j++)               printf("%s\n", strings[j]);           free(strings);       }       static void   /* "static" means don't export the symbol... */       myfunc2(void)       {           myfunc3();       }       void       myfunc(int ncalls)       {           if (ncalls > 1)               myfunc(ncalls - 1);           else               myfunc2();       }       int       main(int argc, char *argv[])       {           if (argc != 2) {               fprintf(stderr, "%s num-calls\n", argv[0]);               exit(EXIT_FAILURE);           }           myfunc(atoi(argv[1]));           exit(EXIT_SUCCESS);       }
方法二:使用Android工具方法

示例:
C++中

<1>.test.cpp  #include   #include   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)

C中

 <1>.创建callstack.cpp   #include    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

kernel打印堆栈

#include 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()。

注意

java经过实践测试。
C++\C部分未经过实际完整测试,其中命令都零散的使用过,若参照使用,请根据实际情况调整,整体思路应该没错。实测部分,后面尽量补上

更多相关文章

  1. Android横向滚动屏幕特效分析
  2. 【边做项目边学Android】小白会遇到的问题--创建Android项目不自
  3. Android(安卓)SharedPreferences总结及优化
  4. android之listview使用方法(一)
  5. Android四大组件的工作过程
  6. Android监听通话正确操作方法介绍
  7. 从头到尾给你讲明白Android(安卓)View实现原理
  8. android充当server服务器
  9. android 应用内悬浮框,并在指定页面显示

随机推荐

  1. Android Studio报错:Ignoring unknown pa
  2. android 如何把新建项目的那个 android a
  3. Android开发实现HttpClient工具类
  4. 第一番 Android 不能进行debug调试
  5. 直播源码Android实现 曲线路径动画
  6. android按键定义
  7. Android应用程序生命同期
  8. Android存储数据到本地文件
  9. android的service中在后台弹出提示框
  10. android中去掉EditText的自动焦点获取