Android Crash分析和解决方法总结

1 POSIX pthread_create原理
1)fork()、pthread_create()、vfork()对应的系统调用分别是sys_fork()、sys_clone()、sys_vfork(),它们在内核中都是通过do_fork()实现的。
2)系统中所有的进程都组织在init_task.tasks链表下面,每个进程的线程组织在每个进程task_sturct->signal的链表下。参考函数for_each_process()和for_each_process_thread()。
3)根据上述分析,Linux用户态和内核线程都由task_struct结构体描述,是一个轻量级的进程,因此内核中current变量可以表示进程、用户态线程和内核线程。

2 Framework Crash
2.1 Monkey测试命令
monkey -v -p com.oem.package  --pct-syskeys 0 5000000

2.2 日志文件路径
/data/anr/trace.txt

debuggerd生成的dump路径:
/data/tombstone

2.3 App Crash原因跟踪
logcat -b events | grep am_crash

grep 搜索多个字符串,正则表达式如下:
grep -E "word1|word2|..."

2.4 bugreport
bugreport dump开始 - vibrator震动一下
bugreport dump结束 - vibrator震动3次

1)ChkBugReport下载
ChkBugReport工具for Android
https://blog.csdn.net/wxlinwzl/article/details/70228503

2)获得并解析bugreport文件
adb shell bugreport > bugreport.txt

java -jar e:\chkbugreport-0.4-185.jar bugreport.txt

2.5 Framework Watchdog
Android Framework Watchdog触发时,会写l(是字母l,不是数字1)到/proc/sysrq-trigger输出所有CPU的backtrace到kernel log:“SysRq : Show Blocked State”

kworker中的u:是unbound的缩写,代表没有绑定特定的CPU,kworker/u2:0中的2是work_pool的ID
pidstat 1 :显示每个CPU上都运行哪些进程,数字1表示每隔一秒打印一次

3 kernel的log机制
3.1 kernel代码中调整loglevel
int old_lvl = console_loglevel;
console_loglevel = \
    CONSOLE_LOGLEVEL_MOTORMOUTH;
// TODO
console_loglevel = old_lvl;

3.2 Linux Kernel动态log
- 需在内核中配置CONFIG_DYNAMIC_DEBUG,并且将debugfs挂载到某个文件夹mount -t debugfs none /sys/kernel/debug/
- 通过echo -n "file xxxxxx.c +p" > /sys/kernel/debug/dynamic_debug/control(或者/d/dynamic_debug/control)来打开调试信息

3.3 Kernel hexdump
print_hex_dump(KERN_INFO, "",
    DUMP_PREFIX_OFFSET, 16, 1,
    buf,
    len,
    true);

4 addr2line和objdump使用
4.1 带有完整调试信息的符号路径
./out/target/product/[PROJECT]/symbols/vendor/lib64/

4.2 addr2line
addr2line -C -f -e libxxx.so <地址>
其中地址为#00 Frame前面显示的pc指向的地址

aarch64-linux-android-addr2line -C -f -e vmlinux <目标地址>

4.3 objdump
objdump -l -C -S libxxx.so > deasm.log
vi deasm.log
输入#00 Frame前面显示的pc指向的地址(需要去掉前面的多个0)

4.4 gdb vmlinux
Use 7-Zip to extract vmlinux from IPK file.
gdb vmlinux
l *func_name+offset_addr

5 Android gdb调试
adb forward tcp:5039 tcp:5039
adb shell gdbserver :5039 --attach $PID &

6 workqueue
kernel/workqueue.c
static int worker_thread(void *__worker)

- 对于create_singlethread_workqueue()而言,即使是对于多CPU系统,内核也只负责创建一个worker_thread()内核进程
- create_workqueue(),对于多CPU系统而言,对每一个CPU,都会生成一个新的worker_thread()进程
- schedule_delayed_work()和schedule_work()对应到默认线程events/X

7 QCOM MSM
7.1 Diagnostics
1)Diag命令格式
CMD_CODE                 - 1 Bytes
SUBSYS_ID                  - 1 Bytes
SUBSYS_CMD_CODE   - 2 Bytes

2)ffbm例子 - Fast Factory Boot Mode
CMD_CODE                 - 1 Bytes,75
SUBSYS_ID                   - 1 Bytes,11
SUBSYS_CMD_CODE   - 2 Bytes,0,53
FFBM_CMD_DODE       - 2 Bytes,0,0
RESERVED                   - 2 Bytes,0,0
RESERVED                   - 2 Bytes,0,0

7.2 Watchdog
1) NS Watchdog bark
如果是死锁的情形,导致pet_watchdog_work没有办法执行,但是kernel能够响应中断。这个情形就会出现dog-bark。

2) NS Watchdog bite
如果是CPU hang了或者当前CPU执行了CPSID(spin_lock_irqsave()就会调用这个指令)导致系统超时无法响应中断(例如核间中断IPI - ping other cpu),到时间会触发bite。HW interrupt dog-bite是由TZ FIQ接管的。

7.3 T32 Simulator
7.3.1 QPST
Use QPST to capture the ram dump via USB, and linux-ramdump-parser-v2 needs vmlinux to parse DDRCS0.bin

strings vmlinux | grep "Linux version"
strings DDRCS0.bin | grep "Linux version"

7.3.2 Commands
1)内核DEBUG时需要打开的MACRO
CONFIG_DEBUG_SPINLOCK = y
CONFIG_MSM_T2_LOG = n   - 读写内存冲掉

2)查看CPU调用栈
- 先填写寄存器
fp(R11)
ip(R12)
sp(R13)
pc(pc)
R0 到 R10
- 填写完成后
v.f
- 假如不写寄存器参数,直接输入v.f,那么输出的是CPU最后的call stack。

3)查看运行队列
View -> Symbols -> Browse -> 输入“runqueues” -> 显示的是基地址base
v.v __per_cpu_offset -> 显示的是偏移地址offset
v.v (struct rq *)(base + offset)

4)显示函数的汇编代码
d.l <函数名字>
例如:d.l fli_printf

5)数据格式
选中一个对象,右键选择“Format”,勾选“Hex”或者“String”。

6)RPM RAM Dump
hansei.py --elf rpm.elf --output my_rpm.log --verbose dumpfile CODERAM.BIN DATARAM.BIN MSGRAM.BIN

7.4 linux-ramdump-parser-v2
https://git.codelinaro.org/clo/la/platform/vendor/qcom-opensource/tools

7.5 crash-utility
This tool runs in Ubuntu to analyze Linux ARM64 crash issue.
https://github.com/crash-utility/crash
make target=ARM64
binary crash is under the current directory.

crash vmlinux --kaslr=0x5d880000 DDRCS0_0.BIN@0x80000000,DDRCS0_1.BIN@0x100000000
parameter kaslr (Kernel Address Space Layout Randomization) comes from OCIMEM.BIN.

7.6 panic_notifier_list
panic_timeout
cat /proc/sys/kernel/panic

7.7 SA8155 EMAC DCC
DCC means Data Capature and Compare.
device/qcom/common/rootdir/etc/init.qti.debug-msmnile.sh
Don't consult ethernet team, but consult stability team for help.

7.8 pstore
CONFIG_PSTORE
CONFIG_PSTORE_CONSOLE
CONFIG_PSTORE_PMSG
CONFIG_PSTORE_RAM
CONFIG_PSTORE_ZLIB_COMPRESS
reserved-memory {
    ramoops@PHYS_ADDR {
        compatible = "ramoops";
    };
};
From /proc/iomem to find a System RAM for ramoops.
pstore.backend=ramoops
ramoops.mem_address=0x60000000
ramoops.mem_size=0x400000
ramoops.record_size=0x4000
ramoops.console_size=0x200000
mount -t pstore pstore /sys/fs/pstore
logs under /sys/fs/pstore
binary: open source pstore-clean

7.9 Lagging
1)使用dumpsys gfxinfo命令可获取128帧的绘制信息,详细包括每一帧绘制的Draw、Process、Execute三个过程的耗时,如果这三个时间总和超过16.6ms即认为发生了卡顿。
2)使用top命令查看是内核卡顿(swapper),还是用户空间卡顿。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值