Android BUG定位

Posted Kevin张俊杰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android BUG定位相关的知识,希望对你有一定的参考价值。

!!!核心思想

耐心追踪 | 大胆假设小心求证 | 对比分析 | ERROR并非ERROR异常并非异常

断点调试

https://blog.csdn.net/johnWcheung/article/details/102620497

日志打印

#打印property(android.os.SystemProperties)
getprop key

#设置property
setprop *[注:persist开头的属性设置是永久保存,ro开头的属性只读,一旦设置,不能更改]

#修改Settings参数
settings put secure eth_dualstack true

#串口输入文本
input text ""

#logcat加时间戳并过滤多个关键字
logcat -v time|grep -e xx -e xx

#抓日志加时间戳、加线程号
logcat -v threadtime

#日志写文件后台执行
logcat -v time > /data/log.txt &【结束先fg,再ctrl+c】
cp /data/log.txt  /mnt/sda/sda1【sync再拔掉U盘】

#命令发送广播并携带参数
am broadcast -a com.android.test --es test_string "this is test string" --ei test_int 100 --ez test_boolean true

#ActivityManager启动应用标志
一般情况下,我们可以将应用启动的时间分为三个时间段A, B和C。A时间段---起始标志Log是ActivityManager: START u0, 系统在这段时间内为启动的Activity创建ActivityRecord,创建或者选择合理的ActivityStack,TaskRecord,将当前Resume的Activity Pause;B时间段---起始标志Log是am_proc_start,系统在这段时间内为启动的应用创建进程;C时间段---起始标志Log是am_set_resumed_activity,这段时间内主要是调用启动Activity的onCreate,onStart,onResume,到最终界面显示结束时间计算,输出对应的Log。

#打印应用启动时间
am start -W -n com.android.settings/.Settings -S

#根据AMS找出启动应用的进程,根据进程号过滤应用的日志

异常分析

Java 异常处理

Android程序异常分析

Force close / ANR / Tombstone

Force close / ANR(/data/anr/traces.txt) 前两者主要是查看当前的进程或者系统框架层的状态和堆栈就基本可以分析出来

tombstone一般是由Dalvik错误、状态监视调试器、C层代码以及libc的一些问题导致的

当系统发生tombstone的时候,kernel首先会上报一个严重的警告信号(signal),上层接收到之后,进程的调试工具会把进程中当时的调用栈现场保存起来,并在系统创建了data/tombstones目录后把异常时的进程信息写在此目录里面,开发者需要通过调用栈来分析整个调用流程来找出出问题的点。

如何分析墓碑日志呢?

#执行目录:out/target/product/xxx/ symbols/system/lib

#基本工具

1.通过backtrace一栏提供的地址查询对应的符号,可以定位到文件,函数,行数

addr2line –aCfe libs $(trace_address)

2.相当于执行多次addr2line,可以直接针对一份crash log使用,会输出所有backtrace里地址对应的symbol

ndk-stack –sym $(lib_directory) –dump $(crash_log_file)

3.Dump the objectfile. 通过汇编代码定位错误的原因,大部分复杂的问题可以通过这种方式得到解决
注:需要指定交叉编译工具链如arm-linux-gnueabihf-objdump

objdump -S $(objfile) > $(output_file) //重定向写入可选

4.列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等

nm -D libdvm.so > dvm.data

注:
1、所谓符号,通常指定义出的函数,全局变量等等
2、c++filt将每个输入的名称看成是改编后的名称(mangled name),并设法确定用于生成该名称的编译器。如果这个名称是一个合法的改编名称,那么,c++filt就输出改编之前的原始名称;如果c++filt无法识别一个改编名称,那它就按原样输出该名称

通过以上工具的分析 ,我们可以得到较完整的调用栈以及调用逻辑的汇编码,然后需要结合ARM架构及ARM汇编的知识(有些情况下可能需要使用gdb)来分析出现tombstone的原因,以下是本人遇到过的一些tombstone的情况:

1.无效的函数指针:指针为NULL或者已经被重新赋值

2.strlen崩溃:导致不完全的栈信息,栈被破坏

3.FILE操作:因为stdio并非线程安全的,多线程操作时,容易出现异常

5.eg: pid: 1658, tid: 13086 >>> system_server <<<
确认问题到底发生在哪个线程中,是主线程还是子线程,这个的判断依据是—如果PIDTID相同,问题出现在父线程;如果PID和TID不相同,问题出在子线程中。

以上是关于Android BUG定位的主要内容,如果未能解决你的问题,请参考以下文章

墓碑机制与生命周期

iOS下的 Fixed BUG

Android MediaPlayer IllegalStateException源码分析定位

Android MediaPlayer IllegalStateException源码分析定位

Android MediaPlayer IllegalStateException源码分析定位

为啥墓碑桶可以用来插入?