背景: 在我们平常开发中经常会遇到一些framework, system_process, art中的一些问题。很多时候我们是需要翻阅代码去查看问题。但是很容易因为某个分支判断不对走错路。 掌握调试技巧后可以帮我更清晰的梳理代码逻辑及复现问题。
准备工作:准备好一台手机或模拟器(建议使用pixel真机,我这边用的是pixel 3xl)用于刷机(用于调试的代码必须和刷入的镜像文件保持一致) .
Java 层调试
第一种方式
[这种方式比较麻烦耗时比较长,这边主要介绍第二种方式]
自己从asop仓库拉取分支代码构建
- 下面地址中选择自己手机机型匹配的代码分支进行代码clone 自己打包镜像文件刷机。
source.android.com/docs/setup/… 我这边选择了
在 Android 8.0.0 (Oreo) 及更高版本中,每个 build 均采用 build ID 格式 PVBB.YYMMDD.bbb[.Cn] 进行标识,其中:
- P 表示平台版本代号的第一个字母,例如 O 表示 Oreo。
- V 表示支持的类别。按照惯例,P 表示主要平台分支。
- BB 是由字母和数字组成的代码,Google 可通过该代码识别 build 所属的确切代码分支。
- YYMMDD 表示相应版本从开发分支细分出来或与开发分支同步的日期。它并不一定是 build 的确切构建日期,因为 Google 常常会在现有 build 中增加细微的更改,并在新 build 中重复使用与现有 build 相同的日期代码。
- bbb 表示具有相同日期代码的不同版本,从 001 开始。
- Cn 是可选的字母数字,表示在现有 PVBB.YYMMDD.bbb build 之上构建的修补程序,从 A1 开始
第二种方式
看手机里系统版本号下载对应版本源码 或者下载已有镜像进行刷机
在aosp相应版本对应分支只下载自己需要调试的代码即可。
分为刷机和代码导入android studio 两个步骤
刷机
下面地址可以找到对应pixel手机的镜像文件。
developers.google.com/android/ima…
-
解锁
- 如需在设备上启用 OEM 解锁功能,请执行以下操作:
- 在“设置”中,点按关于手机,然后点按版本号七次。
- 当看到“您已处于开发者模式”这条消息后,点按返回按钮。
- 点按开发者选项,然后启用 OEM 解锁和 USB 调试(如果 OEM 解锁处于停用状态,请连接到互联网,以便设备可以至少检入一次。如果“OEM 解锁”仍处于停用状态,说明设备可能已被运营商锁定 SIM 卡,系统无法解锁引导加载程序。)
-
重新启动进入引导加载程序,然后使用
fastboot
解锁。- adb reboot bootloader
-
对于新款设备(2015 年及之后发布的设备):
- fastboot flashing unlock
-
对于老款设备(2014 年及之前发布的设备):
- fastboot oem lock
-
下载对应镜像文件 解压刷机
- 重新启动进入引导加载程序
- adb reboot bootloader
- Mac 下执行flash-all.sh文件就行。
- 等待刷机完成重启。
源码导入studio
-
下载源码导入android studio
- 下载自己需要调试的代码就行,比如要查看ActivityThread.java代码
- android.googlesource.com/platform/fr… 点击链接下载压缩包
-
获取android.iml,和android.ipr 文件(这俩个文件可以在aosp下 development/tools/idegen 生成 也可以网上下载)
-
新建文件目录
注意这里我们上面下载的app代码是没有前面的frameworks这种路径的 我需要自己手动创建
最后使用studio的import project将我们新建的目录导入。 新增一个android configuration
- 调试例子 我们在ActivityThread的 handleResumeActivity下一个断点。找到debug按钮 attach到指定进程。来个切换后台前台操作就可以看断点有没有断到了。然后就可以单步调试了。
Native 层调试
native层调试需要带有符号文件的so支持。这个so一般是编译的时候生成的。 以调试art为例子
我这边64位产物路径在/AOSP/out/target/product/crosshatch/symbols/system/lib64/libart.so下。 下面用调试crash 处理举个例子。
-
attach进程 选择java+native调试模式
-
点击以下pause按钮
在LLDB控制台下使用add-dsym添加so目录
br s -n HandleUncaughtExceptions 在HandleUncaughExceptions方法处添加断点
(lldb 使用命令可以查相关文档)
点击运行 再触发crash
System process调式
System process进程Java调试方式和上面说的java层调试有些区别。因为调式的进程必须要是debugable的。我们默认用上面方式刷机System process是非debugable。
下面介绍如何让System process debugable
首先root
-
oem解锁 上文有介绍
-
安装MagisjManager apk
-
获取镜像文件中的boot.img文件 推到手机sdcard下
- adb push /youpath/boot.img /sdcard/Download
-
使用MagisjManager path boot.image 获取到magisk_patched.img
- 将magisk_patched.img 拉到pc本地
- adb reboot bootloader
- fastboot flash boot /youpath/magisk_patched.img
- 重启手机 adb shell ,su 看看能不能申请到root权限。
Android 13需要将boot.img 统一改为init_boot.img flash命令也需要改
fastboot flash init_boot /youpath/magisk_patched.img
- 修改全局debugable
adb shell
su
magisk resetprop ro.debuggable 1
stop;start
- 通过上面java 层调试方法attach到system_process进行调试
APK Smali调试
适用于排查线上包问题 无法通过源码调试排查问题
-
将apk改为可调试
- 使用上述System process方式 全局设置为debugable
- 使用重打包软件手机端(MT管理器) PC端(ApkTool) 修改AndroidManifest 中的debugable为true.
-
Android studio 安装以下插件 smartdea-0.06
-
使用AndroidStudio 打开apk
- 在smali文件中打断点 ,点击调试按钮