1. 为什么要打印函数调用堆栈?

打印调用堆栈可以直接把问题发生时的函数调用关系打出来,非常有利于理解函数调用关系。比如函数A可能被B/C/D调用,如果只看代码,B/C/D谁调用A都有可能,如果打印出调用堆栈,直接就把谁调的打出来了。不仅如此,打印函数调用堆栈还有另一个好处。在Android代码里,函数命名很多雷同的,虚函数调用,几个类里的函数名相同等,即使用source insight工具看也未必容易看清函数调用关系。如果用了堆栈打印,很容易看到函数调用逻辑。那么一个问题来了,Android/kernel本身在发生问题(kernel panic, tombstone, …)时,都可以打出详细的堆栈信息,这里干嘛还要费劲研究打堆栈?答案是发生问题时的堆栈的确很详细,但这里研究的是不影响(准确说是基本不影响)系统运行的境况下,打印出某个情形下的堆栈信息,这个对源代码逻辑研究很有帮助。

2. Linux Kernel

Kernel里最简单,直接有几现成的函数可以使用:

dump_stack() 这个函数打出当前堆栈和函数调用backtrace后接着运行

WARN_ON(x) 这个函数跟dump_stack很像,它有个条件,如果条件满足了就把stack打出来。

打印出来的结果都在kernel log里,一般dmesg命令就可以看到了

3. Native C++

Android在新版(至少5.0, 6.0)里加入了CallStack类,这个类可以打出当前的backtrace。用法很简单:

Ø  前面确保包含头文件#include <utils/CallStack.h>

Ø  Android.mk的库依赖列表(LOCAL_SHARED_LIBRARIES)里包含libutils,一般都已经包含了。

Ø  然后在要打印堆栈处加入android::CallStack cs("haha");

"haha"是在logcat输出的TAG,这里可以自己定义。如果上下文已经在android namespace里,”android::”前缀就不必加了。

Native C++的输出log可以在logcat里看到。

注意,在网上的一些文档里说要这么用:

CallStack stack;

stack.update();

stack.dump();

这样做已经不行了,在新版Android里编译不过。

4. Native C

Android对C的堆栈打印支持不太好。过去网上的文章一般是推荐libcorkscrew.so,并加入大段代码来unwind_backtrace。新版Android上libcorkscrew已经被拿掉了,网上的加载libcorkscrew库的方法自然就不能用了。

一个简单方法是用C语言调C++的函数,对,就是extern “C”。

先在项目里加入一个c++文件,比如callstack.cpp,里面是:

#include <utils/CallStack.h>

extern "C" void dumping_callstack(void);

void dumping_callstack(void)

{

         android::CallStack cs("haha");

}

在项目里再加入一个c++的头文件,比如callstack.h,里面是:

void dumping_callstack(void);

在Android.mk里源文件列表LOCAL_SRC_FILES里加入callstack.cpp,确保libutils在依赖列表里。

在native C里include callstack.h后直接调用dumping_callstack()就可以了。

这个log也可以在logcat里看到。

5. Java

Java最简单,它的backtrace最详细,连文件名和行号都打出来了:

Exception e = new Exception("haha");

e.printStackTrace();

log在logcat里看以看到。

最新文章

  1. 1-ser2008系统封装实验报告
  2. Android事件分发机制理解
  3. Erlang 103 Erlang分布式编程
  4. Storm启动流程简介
  5. 从零开始--系统深入学习IOS(使用Swift---带链接)
  6. [收藏]Asp.net MVC生命周期
  7. redhat linux 安装mysql5.6.27
  8. [poj 3691]DNA repair
  9. apk反编译(2)smali语言及文件
  10. 学习C++ Primer 的个人理解(一)
  11. wpf 自定义RadioButton控件样式
  12. 使用JS截取字符串函数详解
  13. 蓝桥网试题 java 基础练习 回文数
  14. android弹力效果菜单、组件化项目、电影票选座控件的源码
  15. 2.20 绕过验证码(add_cookie)
  16. 触摸屏 adb调试
  17. mybatis spring boot深入
  18. (转)Xen Server删除Local Storage
  19. 8 -- 深入使用Spring -- 4...5 AOP代理:基于注解的“零配置”方式
  20. javascript闭包使用 分类: JavaScript 2015-05-01 11:34 652人阅读 评论(3) 收藏

热门文章

  1. SqlCacheDependency轮询数据库表的更改情况的频率
  2. js中出现问题--Type Syntax error on token &quot;catch&quot;, Identifier expected jquery.js
  3. .parent()和.parents()的区别
  4. 导入工程“The import android cannot be resolved”错误
  5. Postman工具——请求与响应
  6. 简单CSS3动画
  7. 在.Net下使用redis基于StackExchange.Redis--登录功能
  8. RNN、LSTM、Char-RNN 学习系列(一)
  9. BlockingQueue实现阻塞队列
  10. 在ios7中使用zxing