如何使用gdb等工具调试Android zygote进程,实现断点、单步执行等操作
调试Android Zygote进程的可行方案
以下是可实现设置断点、单步执行、查看寄存器等常规调试操作的实操步骤:
1. 环境准备(核心前提,多数调试失败都是环境不符合要求)
- 必须使用Android userdebug/eng版本 镜像,不要用普通user版本镜像,也不要用第三方适配的VMware、公版qemu镜像,优先选择AOSP官方编译对应架构的userdebug镜像,这类镜像默认开放调试权限
- 启动设备后先获取root权限、关闭selinux:
adb root adb remount adb shell setenforce 0 - 确认调试属性开启:执行
adb shell getprop ro.debuggable,返回值为1即为正常,若返回0执行adb shell setprop ro.debuggable 1后重启设备
2. 两种调试场景的操作方法
场景1:调试Zygote启动早期代码
如果需要调试Zygote刚启动的初始化逻辑,需要让Zygote启动时自动暂停等待调试器挂载:
- 执行命令
adb shell setprop debug.zygote.wait_for_debugger 1后重启Zygote,此时Zygote启动后会自动卡住,等待调试器连接
场景2:调试运行中Zygote的逻辑
- 先获取Zygote进程PID:
adb shell ps -A | grep zygote,64位架构设备一般会有zygote64和zygote32两个进程,按需选择对应进程的PID即可
3. GDB调试实操
3.1 设备端启动gdbserver
- 把对应架构的gdbserver(从对应版本的NDK或AOSP编译产物中获取)推到设备并赋权:
adb push gdbserver /data/local/tmp/ adb shell chmod +x /data/local/tmp/gdbserver - 启动gdbserver关联Zygote进程:
adb shell /data/local/tmp/gdbserver :1234 --attach <替换为上一步拿到的Zygote PID> - 本地做端口转发:
adb forward tcp:1234 tcp:1234
3.2 本地GDB连接调试
- 打开本地对应架构的GDB程序(比如aarch64架构用
aarch64-linux-android-gdb) - 加载对应版本的符号表:
file <AOSP根目录>/out/target/product/<设备名>/symbols/system/bin/app_process64(32位Zygote对应app_process32),符号表必须和设备运行的镜像版本完全一致,否则会出现断点不触发、栈解析错误的问题 - 连接远程调试服务:
target remote :1234 - 连接完成后即可正常使用常规GDB命令调试:
b 函数名/地址设置断点、si单步步入、info registers查看寄存器值,操作逻辑和调试普通Native进程完全一致
4. 常见问题排查
- 若attach进程失败,优先检查是否成功获取root权限、selinux是否关闭、gdbserver架构是否和Zygote进程架构匹配
- 若断点设置后不触发,优先检查加载的符号表版本是否和设备运行的
app_process版本完全匹配
内容的提问来源于stack exchange,提问作者sutungpo
相关产品推荐
相关产品推荐

