安卓系统常见问题如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.mzph.cn/web/53598.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spark 任务与 Spark Streaming 任务的差异详解

Spark 任务与 Spark Streaming 任务的主要差异源自于两者的应用场景不同&#xff1a;Spark 主要处理静态的大数据集&#xff0c;而 Spark Streaming 处理的是实时流数据。这些差异体现在任务的调度、执行、容错、数据处理模式等方面。 接下来&#xff0c;我们将从底层原理和源…

408选择题笔记|自用|随笔记录

文章目录 B树&#xff1a;访问节点建堆&#xff01;将结点插入空堆广义指令求每个子网可容纳的主机数量虚拟内存的实现方式文件目录项FCB和文件安全性管理级别索引文件三种存取方式及适用器件成组分解访问磁盘次数 C语言标识符 最小帧长物理传输层介质 局域网&广域网考点总…

AIGC基础工具-用于数据分析和数据处理的核心库Pandas介绍

文章目录 1. Pandas 的核心数据结构1.1 Series创建 SeriesSeries 重要属性示例 1.2 DataFrame创建 DataFrameDataFrame 重要属性示例 2. Pandas 数据的导入与导出2.1 读取 CSV 文件2.2 读取 Excel 文件2.3 写入 CSV 文件2.4 读取 JSON 文件 3. Pandas 的数据操作3.1 数据选择和…

IPsec-Vpn

网络括谱图 IPSec-VPN 配置思路 1 配置IP地址 FWA:IP地址的配置 [FW1000-A]interface GigabitEthernet 1/0/0 [FW1000-A-GigabitEthernet1/0/0]ip address 10.1.1.1 24 [FW1000-A]interface GigabitEthernet 1/0/2 [FW1000-A-GigabitEthernet1/0/2]ip address

开源 AI 智能名片与 S2B2C 商城小程序:嫁接权威实现信任与增长

摘要&#xff1a;本文探讨了嫁接权威在产品营销中的重要性&#xff0c;并结合开源 AI 智能名片与 S2B2C 商城小程序&#xff0c;阐述了如何通过与权威关联来建立客户信任&#xff0c;提升产品竞争力。强调了在当今商业环境中&#xff0c;巧妙运用嫁接权威的方法&#xff0c;能够…

修改Git配置信息:用户名

在Git中&#xff0c;用户名&#xff08;user.name&#xff09;和邮箱地址&#xff08;user.email&#xff09;是用于识别Git操作&#xff08;如提交&#xff09;的标识信息。如果你需要修改Git用户名&#xff0c;你可以通过Git命令行界面来修改这个设置。以下是具体的步骤&…

rust属性宏

1. #[repr(xxx)] repr全称是 “representation”,即表示、展现的意思。在#[repr(u32)]中,u32表示无符号 32 位整数。这意味着被这个属性修饰的类型将以 32 位无符号整数的形式在内存中存储和布局。例如,如果有一个枚举类型被#[repr(u32)]修饰: #[repr(u32)] enum MyEnum {…

AI 智能名片链动 2+1 模式商城小程序中的体验策略

摘要&#xff1a;本文探讨了在 AI 智能名片链动 21 模式商城小程序中&#xff0c;体验策略如何服务于用户体验&#xff0c;以及与产品策略的区别。重点分析了该小程序如何通过关注用户在使用过程中的流畅度、视觉体感等方面&#xff0c;实现“让用户用得爽”的目标&#xff0c;…

微积分复习笔记(2):多变量微积分

一元函数: 可导 ⟺ \iff ⟺ 可微 ⟹ \implies ⟹ 连续 ⟹ \implies ⟹ 极限存在. 多元函数: 偏导连续 ⟹ \implies ⟹ 可微 ⟹ \implies ⟹ 连续 ⟹ \implies ⟹ 极限存在; 可微 ⟹ \implies ⟹ 偏导存在. lim ⁡ x → 0 , y → 0 x y x 2 y 2 0 \lim_{x\to 0,y\to 0}…

c++常用工具类函数

递归读取文件名 void listFiles(const std::string& path,std::vector<std::string>&vec) { DIR* dir; struct dirent* entry; struct stat statbuf; if ((dir opendir(path.c_str())) nullptr) { std::cerr << "Error opening directory: " &…

JS中的事件和DOM操作

一、事件[重要] 1、 事件介绍 事件: 就是发生在浏览器(页面)上一件事,键盘事件,鼠标事件,表单事件,加载事件等等 2、 事件绑定方式 事件要想发生,就得将事件和标签先绑定(确定哪个标签发生什么事情,又有什么响应) 一个完整的事件有三部分 事件源(标签),哪里发出的事. 什么事(…

德勤校招网申笔试综合能力测试SHL题库与面试真题攻略

德勤的综合能力测试&#xff08;General Ability&#xff09;是其校园招聘在线测评的关键环节&#xff0c;旨在评估应聘者的多项认知能力。以下是对这部分内容的全面整合&#xff1a; 综合能力测试&#xff08;General Ability&#xff09; 测试时长为46分钟&#xff0c;包含…

Linux 文件权限详解与管理

文章目录 前言一、文件权限概述1. 权限表示格式2. 权限组合值 二、查看文件权限三、修改文件所有者与所属组1. 使用 chown 修改文件所有者2. 使用 chgrp 修改文件所属组3. 添加所有者 四、修改文件权限1. 符号方式2. 八进制方式3. 实际修改 总结 前言 在 Linux 系统中&#xf…

VS Code调整字体大小

##在工程目录底下.vscode/settings.json添加设置参数 {"editor.fontSize": 15,"window.zoomLevel": 1.5 }

MySQL—存储过程详解

基本介绍 存储过程和函数是数据库中预先编译并存储的一组SQL语句集合。它们的主要目的是提高代码的复用性、减少数据传输、简化业务逻辑处理&#xff0c;并且一旦编译成功&#xff0c;可以永久有效。 存储过程和函数的好处 提高代码的复用性&#xff1a;存储过程和函数可以在…

Redis6.0.9配置redis集群

写在前面 最近在完成暑期大作业&#xff0c;期间要将项目部署在云服务器上&#xff0c;其中需要进行缓存的配置&#xff0c;决定使用Redis&#xff0c;为了使系统更加健壮&#xff0c;选择配置Redis-Cluster。由于服务器资源有限&#xff0c;在一台服务器上运行6个Redis Instan…

docker desktop windows stop

服务docker改为启动 cmd下查看docker版本 {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["https://hub.atomgit.com/"]…

三目运算判断字母大小写-C语言

1.问题&#xff1a; 输入一个字符&#xff0c;判别它是否为大写字母&#xff0c;如果是&#xff0c;将它转换成小写&#xff0c;如果不是&#xff0c;不转换。然后输出最后得到的字符&#xff0c;要求使用三目运算符。 2.解答&#xff1a; 用条件表达式来处理&#xff0c;当字…

前端框架对比和选择

前端框架在现代Web开发中扮演着至关重要的角色&#xff0c;它们通过提供标准化的方法来构建用户界面&#xff0c;极大地提高了开发效率、降低了维护成本&#xff0c;并提升了用户体验。以下是一些常见前端框架的对比&#xff1a; React 组件化与虚拟DOM&#xff1a;React采用组…

JAVA输入输出处理技术

java处理的数据 文件数据 流式数据&#xff1a;字节流&#xff08;Byte,一次读写8位二进制数&#xff09; 字符流(Character&#xff0c;一次读写16位二进制数) java的I/O分类 基于字节操作的I/O接口&#xff1a;InputStream OutputStream&#xff08;8位&#xff09; 基于字…