当前位置: 首页 > news >正文

【转】Android下面打印进程函数调用堆栈(dump backtrace)的方法

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里看以看到。

转载于:https://www.cnblogs.com/CoderTian/p/6149332.html

相关文章:

  • 算法导论学习笔记——找数组中第i小的元素
  • 获取验证码
  • 在最坏情况下,利用n + ┌lgn┐ - 2 次比较,即可找到 n 个元素中的第2小元素
  • 牛客网上的剑指offer题目
  • 算法导论学习补充——希尔排序
  • java虚拟机学习笔记——java虚拟机内部体系概述(第五章)
  • java虚拟机学习笔记——java class文件的内容(第六章)
  • 《java jdk7学习笔记》之java三大平台
  • java类的装入
  • LR常用函数以及调用自定义函数
  • java类加载器体系结构
  • MySQL 导入数据
  • java虚拟机学习笔记——类型和对象的生命周期(第七章)
  • jQuery中的100个技巧(译)
  • 子类为什么不能重写父类的静态方法
  • express + mock 让前后台并行开发
  • gf框架之分页模块(五) - 自定义分页
  • GitUp, 你不可错过的秀外慧中的git工具
  • java2019面试题北京
  • nfs客户端进程变D,延伸linux的lock
  • npx命令介绍
  • PHP 7 修改了什么呢 -- 2
  • Selenium实战教程系列(二)---元素定位
  • use Google search engine
  • 阿里云Kubernetes容器服务上体验Knative
  • 闭包--闭包之tab栏切换(四)
  • 测试如何在敏捷团队中工作?
  • 排序算法学习笔记
  • 配置 PM2 实现代码自动发布
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 软件开发学习的5大技巧,你知道吗?
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 微信开源mars源码分析1—上层samples分析
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 小程序01:wepy框架整合iview webapp UI
  • Semaphore
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 如何在招聘中考核.NET架构师
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #Linux(make工具和makefile文件以及makefile语法)
  • #pragam once 和 #ifndef 预编译头
  • #vue3 实现前端下载excel文件模板功能
  • (23)Linux的软硬连接
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)ssm高校实验室 毕业设计 800008
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (一)认识微服务
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)jQuery 基础
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • (转)原始图像数据和PDF中的图像数据