一、准备工作
1、下载并编译Android系统源码
这里比较灵活,可以下载公司内部机型的代码,也可以下载原生AOSP的代码
环境配置参考
源码下载参考
编译运行参考
全部编译整个代码工程,中间如果有什么问题可以参考
2、设置PC端环境
如果要调试自己build的版本,就可以使用out目录下的symbols
这里带一句,symbols是带有debug信息的二进制库或可执行文件,用以调试
除了symbols之外我们还需要gdb(client),可以在源码目录的prebuilts目录下找到他们,为了方便,可以直接设置环境变量
3、获取调试的权限
最好使用userdebug或者eng build,实在不行也可以使用root后的user build系统,但是要同时关掉selinux
adb shell setenforce 0
否则无法调试
4、设置手机端环境
如果是user build,手机中没有gdbserver,所以需要手动push一个,gdbserver可以去源码目录下的prebuilts目录中搜索一下,但是这里要区分一下gdbserver和gdbserver64
如果是要调试64位的进程就需要gdbserver64
通过以下命令push到手机中
adb root
adb disable-verity
adb reboot
等待重启完成
adb remount
adb push prebuilts/misc/android-arm/gdbserver/gdbserver /system/bin/
二、开始调试
这里假设要调试的是zygote进程,首先要知道zygote进程对应的可执行文件,这里是app_process32,64位的zygote64对应的是app_process64
1、gdbserver attach到想要调试的进程
adb shell
ps | grep zygote
gdbserver :1991 --attach 303
这里的端口可以随便指定一个空闲的即可
2、gdb client连接到gdbserver
通过执行以下命令进行连接
adb forward tcp:1991 tcp:1991
arm-linux-androideabi-gdb
target remote:1991
这里需要说一下,如果需要调试的进程是64位的,就要用64位的gdb client然后配合gdbserver64
aarch64-linux-android-gdb
3、load对应可执行文件
file /Volumes/1TB-HD/Images/cancro/16.11.01/compressed_cancro_mm-alpha_2016.11.01.18.08_0e62b9421b/out/target/product/cancro/symbols/system/bin/app_process32
4、Set sysroot路径
set sysroot /Volumes/1TB-HD/Images/cancro/16.11.01/compressed_cancro_mm-alpha_2016.11.01.18.08_0e62b9421b/out/target/product/cancro/symbols
5、设置源码目录
set dir /Volumes/1TB-HD/CodeRoot/CANCRO_ALPHA/
6、设置断点
b frameworks/base/core/jni/fd_utils-inl.h:180
Breakpoint 1 at 0xb6e24f0c: file frameworks/base/core/jni/fd_utils-inl.h, line 180.
7、继续运行
c
Continuing.
[New Thread 5872]
[New Thread 5873]
[New Thread 5874]
[New Thread 5875]
操作并等待运行到断点处
Breakpoint 1, FileDescriptorInfo::Restat (this=0xb4cbd620) at frameworks/base/core/jni/fd_utils-inl.h:182
warning: Source file is more recent than executable.
182 ALOGE("Restat, st_nlink == 8, (%s, fd=%d) : f_stat.st_nlink=%llu,0x%llX file_stat.st_nlink=%llu,0x%llX",
8、查看变量对应的值
p f_stat.st_nlink
$1 = 1
三、扩展功能
到这里对于刚接触gdb调试同学也有了入门的知识,对于gdb老手估计是要玩飞的节奏。。。
但是这里要说一下,如果要调试的是framework相关的进程的native代码,可能会受到system server的watchdog的影响,1分钟没有及时响应操作就会触发watchdog而kill到system server进程,zygote也会跟着挂掉,这里有个小技巧可以用一下,就是在调试的过程中,如果需要耗时查看一些运行时状态,可以先执行 adb shell am hang
防止超时重启,查看完毕想要继续执行,就Ctrl+c终止掉am hang即可继续执行,后面就重复这个过程即可。
另外还有一种方式就是用Android Studio在线调试,把断点加在watchdog里面,配置gdb native调试。