搭建Android源码调试环境(三)——调试C/C++(使用CLion)

前言

aosp自带gdbclient.py脚本用于调试

kevin@kevin-GS60-2PL /mnt/2ffc0bac-5896-499a-9ae6-79e610162482/aosp $ gdbclient.py 
usage: gdbclient.py [-h] [--adb ADB_PATH] [-a | -d | -e | -s SERIAL]
                    (-p PID | -n NAME | -r ...) [--port [PORT]]
                    [--user [USER]]
gdbclient.py: error: one of the arguments -p -n -r is required

-n 通过进程名来调试,-p 通过进程id来调试
虽然使用该脚本工具调试没有问题,但是操作上来说还是不如IDE来得直观方便快捷,所以就考虑使用IDE来进行的C/C++调试

AOSP的C/C++调试原理,就是在Android端运行gdbserver,然后PC端使用gdb通过tcp连接到gdbserver,所以只要知道原理,使用CLion也是可以进行调试的。使用其它的C/C++ IDE理论上也是可以进行调试的,我之所以选择CLion一是因为其跨平台,二是因为在Linux平台上目前个人认为最好用的C/C++ IDE了

CLion配置

1. 编写CMakeLists.txt

目前CLion只能识别CMake项目,所以为了使用CLion调试AOSP,需要编写CMakeList.txt。否则无法使用远程调试功能。
参考这篇博客Android Native C/C++ 使用CLion阅读/编译技巧

2. 导入Aosp项目,配置远程调试

导入aosp需要等待index完成。
然后就可以新建远程调试了

  1. 选择Edit Configurations
    搭建Android源码调试环境(三)——调试C/C++(使用CLion)_第1张图片
  2. 点击加号,然后选择GDB Remote Debug
    搭建Android源码调试环境(三)——调试C/C++(使用CLion)_第2张图片
  3. 按下图进行配置("/mnt/2ffc0bac-5896-499a-9ae6-79e610162482/aosp"这个是我Android源码的目录,将其替换成自己源码的目录即可)
    搭建Android源码调试环境(三)——调试C/C++(使用CLion)_第3张图片
    主要是设置调试符号所在目录,以及路径映射

3. 编写android_gdbserver脚本

~/script/start_android_gdb_server.sh

#!/usr/bin/env bash
gdbServerPid=`adb shell ps | grep gdbserver | awk '{print $2}'`

if [[ "" != ${gdbServerPid} ]]; then
    adb shell su -c "kill ${gdbServerPid}"
fi

adb forward tcp:1234 tcp:1234

if [[ `adb shell whoami` == 'root'  ]]; then
    is_root=true
fi

if [[ -n $1 ]]; then
	appPid=`adb shell ps | grep ${1} | awk '{print $2}'`
	if [[ -n ${appPid} ]]; then
        if [[ $is_root == true  ]]; then
            adb shell gdbserver :1234 --attach ${appPid}
        else
            adb shell su -c "gdbserver :1234 --attach ${appPid} "
        fi
    else
    	echo "$1 进程没有启动!"
	fi
else
	echo "请设置要调试的进程名(app的进程名是包名)。例如 $0 "
fi

通过软连接连接到 ~/bin目录下

ln -s ~/script/start_android_gdb_server.sh ~/bin/android_gdb_server

4. 调试

这里通过调试zygote来演示如何使用CLion调试

  1. 先停止zygote服务
    adb shell stop zygote
    
  2. 启动gdbserver
    kevin@kevin-GS60-2PL /mnt/2ffc0bac-5896-499a-9ae6-79e610162482/aosp $ android_gdb_server init
    Attached; pid = 1
    Listening on port 1234
    Remote debugging from host 127.0.0.1
    
    
  3. 点击调试按钮(右边绿色按钮)
    在这里插入图片描述
    如下图表示连接成功
    搭建Android源码调试环境(三)——调试C/C++(使用CLion)_第4张图片
  4. 设置断点位置如下
    system/core/init/service.cpp
    bool Service::Start() {
        // Starting a service removes it from the disabled or reset state and
        // immediately takes it out of the restarting state if it was in there.
        flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
    
        // Running processes require no additional work --- if they're in the
        // process of exiting, we've ensured that they will immediately restart
        // on exit, unless they are ONESHOT.
        if (flags_ & SVC_RUNNING) {//在这里断点
            return false;
        }
        ...
    }
    
  5. 启动zygote服务
    adb shell start zygote
    
  6. 停止在断点处
    搭建Android源码调试环境(三)——调试C/C++(使用CLion)_第5张图片

常见问题解决

  1. 调试时变量显示 potimized out
    这是因为clang编译时默认会进行优化,可以在Android.dp的cppflags中加入-O0禁止优化,然后重新编译m -j8,重启模拟器再次执行调试就可以了。

你可能感兴趣的:(android)