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

安卓系统常见问题如native crash,卡顿卡死定位工具命令技巧-android framework实战开发

背景:

有学员朋友近来有问到一些安卓系统开发过程中的一些核心小技能小技巧等,比如native crash在企业里面该如何准确定位具体代码函数,程序卡住,或者长时间没反应,想要看看卡在代码的哪里。针对以上的一些问题,我这边分享一些工作中常用积极该类问题的一些辅助工具命令技巧,帮助大家更好的在工作中定位这类问题。

Native Crash堆栈分析工具实战

先看看常见native日志中可以获取的堆栈情况


09-24 16:34:53.233  6918  6918 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-24 16:34:53.233  6918  6918 F DEBUG   : LineageOS Version: '21.0-20240413-UNOFFICIAL-nx563j'
09-24 16:34:53.233  6918  6918 F DEBUG   : Build fingerprint: 'nubia/NX563J/NX563J:7.1.1/NMF26X/eng.nubia.20171019.101529:user/release-keys'
09-24 16:34:53.233  6918  6918 F DEBUG   : Revision: '0'
09-24 16:34:53.233  6918  6918 F DEBUG   : ABI: 'arm64'
09-24 16:34:53.233  6918  6918 F DEBUG   : Timestamp: 2024-09-24 16:34:53.213262674+0800
09-24 16:34:53.233  6918  6918 F DEBUG   : Process uptime: 3s
09-24 16:34:53.233  6918  6918 F DEBUG   : Cmdline: robert -rec:/data/event
09-24 16:34:53.234  6918  6918 F DEBUG   : pid: 6914, tid: 6914, name: robert  >>> robert <<<
09-24 16:34:53.234  6918  6918 F DEBUG   : uid: 0
09-24 16:34:53.234  6918  6918 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
09-24 16:34:53.234  6918  6918 F DEBUG   : Cause: null pointer dereference
09-24 16:34:53.234  6918  6918 F DEBUG   :     x0  0000006404f5c28c  x1  0000006404f5cd12  x2  0000000000000000  x3  0045565f00000000
09-24 16:34:53.234  6918  6918 F DEBUG   :     x4  0000008000000000  x5  0000000000000000  x6  0000000080000000  x7  454b005342415f57
09-24 16:34:53.234  6918  6918 F DEBUG   :     x8  4acdd30573c30611  x9  0000000000000000  x10 0000000000000001  x11 0000006404f5dde8
09-24 16:34:53.234  6918  6918 F DEBUG   :     x12 0000006404f5dcde  x13 0000000000000000  x14 0000000000000001  x15 0000000000000000
09-24 16:34:53.234  6918  6918 F DEBUG   :     x16 0000006404f64c08  x17 00000077aa0ce500  x18 00000077ab97c000  x19 0000000000000009
09-24 16:34:53.234  6918  6918 F DEBUG   :     x20 0000006404f5baad  x21 0000006404f66000  x22 00000077aae3f000  x23 0000007ff03cad80
09-24 16:34:53.234  6918  6918 F DEBUG   :     x24 0000007ff03cad80  x25 0000000000000000  x26 0000000000000000  x27 0000006404f66000
09-24 16:34:53.234  6918  6918 F DEBUG   :     x28 0000006404f5cd12  x29 0000007ff03cad00
09-24 16:34:53.234  6918  6918 F DEBUG   :     lr  0000006404f60b58  sp  0000007ff03cacd0  pc  0000006404f5ff18  pst 0000000000000000
09-24 16:34:53.234  6918  6918 F DEBUG   : 4 total frames
09-24 16:34:53.234  6918  6918 F DEBUG   : backtrace:
09-24 16:34:53.234  6918  6918 F DEBUG   :       #00 pc 0000000000009f18  /system/bin/robert (print_all_event()+60) (BuildId: 52b288fb7098ea1a378db332a4c000bf)
09-24 16:34:53.234  6918  6918 F DEBUG   :       #01 pc 000000000000ab54  /system/bin/robert (startRecord()+2620) (BuildId: 52b288fb7098ea1a378db332a4c000bf)
09-24 16:34:53.234  6918  6918 F DEBUG   :       #02 pc 000000000000afd8  /system/bin/robert (recordEvent(char*)+228) (BuildId: 52b288fb7098ea1a378db332a4c000bf)
09-24 16:34:53.234  6918  6918 F DEBUG   :       #03 pc 0000000000052610  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+104) (BuildId: c74277f481a383c87215b672f6465e24)

上面堆栈都是一些地址码和大概的函数堆栈,所以一般没办法直接和java代码一样定位到具体的行数等。一般user版本也就只有上面的crash的堆栈信息,虽然没办法定位到具代码crash行数,但是可以得到一些线索:

1、根据堆栈可以得出这个其实是一个空指针的crash在这里插入图片描述
2、crash的地方可以大概定位到是在 /system/bin/robert 的print_all_event()方法
在这里插入图片描述但是具体函数user版本的话就看不出来,如果可以复现的话其实这个问题也好处理,因为可以考虑直接系统上复现,使用源码进行debug到具体函数,再不行还可一行行打log也可以缩小定位。

有源码+可以复现crash情况下,可以使用工具llvm-addr2line定位具体代码行数,方法如下:

~/test/aosp/out/target/product/xxx/symbols/system/lib64$ ~/test/aosp/prebuilts/clang/host/linux-x86/clang-r416183b/bin/llvm-addr2line -Cfe xxx.so(或者bin) xxxx(16进制地址)
xxxxx(方法全名)

上面来举例,堆栈获取最顶部的一行

#00 pc 0000000000009f18 /system/bin/robert (print_all_event()+60)

0000000000009f18就是16进制地址 robert就是bin print_all_event方法
就拿上面案例来测试:

test@test:~/disk2/nx563j_aosp14/out/target/product/nx563j/symbols/system/bin$ ~/disk2/nx563j_aosp14/prebuilts/clang/host/linux-x86/clang-r487747c/bin/llvm-addr2line -Cfe robert 0000000000009f18 print_all_event
testNull()
robert/getevent.cpp:270
print_all_event

去除路径核心就是 :
llvm-addr2line -Cfe robert 0000000000009f18 print_all_event
在这里插入图片描述

上面经过工具后既可以得到出错代码是在
robert/getevent.cpp:270
下面看看这个270行代码
在这里插入图片描述确实有空指针

进程卡住,卡顿定位backtrace获取分析

经常调试偶尔发现app可能卡住,没反应的情况,这个时候就很希望知道卡住这时候的进程的一个运行情况,希望可以得到一个和anr trace一样的文件来方便分析定位线程状态,即想要获取进程的backtrace。
注意获取进程backtrace方法都需要root

apk打印出当前进程backtrace

使用命令:

kill -3 pid (只针对apk类型的生效)

执行后在/data/anr/目录生成backtrace文件

NX563J:/ # ps -A | grep anr                                                                                                                                                                                       
u0_a181       7449 22013   14655980  76492 futex_wait_queue_me 0 S com.example.anrdemo
NX563J:/ # kill -3 7449

pull出anr下面的文件及打开:

adb pull /data/anr ~/tmp/

在这里插入图片描述

在这里插入图片描述可以看出卡顿时候其实是main主线程卡在onResume方法里面,线程处于sleep
在这里插入图片描述

native程序打印backtrace

使用debuggerd 命令
debuggerd -b pid (针对native bin)

案例如下:
robert进程的backtrace

NX563J:/ # ps -A | grep robert
root          7629  7622   10830444   1872 do_sys_poll         0 S robert
NX563J:/ # debuggerd -b 7629


----- pid 7629 at 2024-09-24 17:14:02.315686219+0800 -----
Cmd line: robert -rec:/data/event
ABI: 'arm64'

"robert" sysTid=7629
    #00 pc 00000000000ab758  /apex/com.android.runtime/lib64/bionic/libc.so (__ppoll+8) (BuildId: c74277f481a383c87215b672f6465e24)
    #01 pc 0000000000065ed0  /apex/com.android.runtime/lib64/bionic/libc.so (poll+92) (BuildId: c74277f481a383c87215b672f6465e24)
    #02 pc 000000000000a2b4  /system/bin/robert (startRecord()+424) (BuildId: 7005ff744c2b0ed72a670bb8f0bd61e9)
    #03 pc 000000000000afcc  /system/bin/robert (recordEvent(char*)+228) (BuildId: 7005ff744c2b0ed72a670bb8f0bd61e9)
    #04 pc 0000000000052610  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+104) (BuildId: c74277f481a383c87215b672f6465e24)

----- end 7629 -----

更多framework详细代码和资料参考如下链接
投屏专题部分:
https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg
hal+perfetto+surfaceflinger

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615


http://www.kler.cn/news/319492.html

相关文章:

  • Java_Day05学习
  • 搜维尔科技:通过xsens动作捕捉为影视角色注入生命
  • 前端框架的对比和选择
  • MySQL备份与恢复详解
  • Anaconda/Miniconda的删除和安装
  • rapidocr 提取汇总
  • 可以写自动化测试工具的AI工具
  • [笔记]交流接触器
  • UR机器人坐标系转化
  • C++系列-Stackqueue
  • Qt中多语言的操作(以QtCreator为例)
  • Android个性名片界面的设计——约束布局的应用
  • 「iOS」——单例模式
  • Angular面试题三
  • javascript的闭包学习
  • Vue报错 ‘vite‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
  • 电路板上电子元件检测系统源码分享
  • Spring Boot 配置全流程 总结
  • 视频转文字工具:开启视频内容深度挖掘的钥匙
  • centos7 docker部署nacos
  • HCIA--实验十七:EASY IP的NAT实现
  • 拒绝信息泄露!VMD滚动分解 + Informer-BiLSTM并行预测模型
  • PyFluent常用代码 1
  • QT开发模式(二):QML/JS/C++混合编程
  • 中国电子学会202312青少年软件编程(Python)等级考试试卷(四级)真题
  • 基于VUE的医院抗生素使用审核流程信息化管理系统
  • 前端如何实现截图?
  • webView2 隐藏滚动条
  • 【数据结构初阶】排序算法(上)插入排序与选择排序
  • echarts实现地图下钻并解决海南群岛显示缩略图