1. 东西篇
关于 Android 体系源码中的 C/C++ 代码,CLion 是一个不错的东西。
较新版本的 Android 源码支撑运用 AIDEgen 调用 Clion 检查 C/C++ 代码。但是,关于咱们学习运用的 Android10 是不支撑的。不过咱们能够经过其他办法完成 Clion 检查 C/C++ 代码:
# 准备工作
source build/envsetup.sh
lunch aosp_x86_64-eng #挑选一个适宜的 Product
export SOONG_GEN_CMAKEFILES=1
export SOONG_GEN_CMAKEFILES_DEBUG=1
make -j16
接着咱们就能够运用 Clion 打开咱们的代码了。
假定咱们需求看 SurfaceFlinger 相关代码:
#体系源码目录下查找
find . -name "SurfaceFlinger*"
./frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
./frameworks/native/services/surfaceflinger/SurfaceFlingerProperties.cpp
./frameworks/native/services/surfaceflinger/SurfaceFlinger.h
./frameworks/native/services/surfaceflinger/SurfaceFlingerProperties.h
./frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.h
.......
这儿咱们知道 SurfaceFlinger 界说在 frameworks/native/services
目录:
接着咱们打开 Clion,点击 Open:
挑选 out/development/ide/clion/frameworks/native
目录
这样咱们就能够运用 CLion 检查体系源码了,需求注意的是咱们的源码需求在 External Libraries 中检查:
咱们也能够经过点击 Change Project Root 按钮调整目录结构:
2. 手段篇
阅读源码首要两个手段:
- 打印 Log + 打印调用仓库
- 运用 CLion 调试
这儿咱们修正 SurfaceFlinger 的主函数 main_surfaceflinger.cpp 来演示打印 Log 和打印调用仓库:
//log的头文件
#include "log/log.h"
//直接 define LOG_TAG 会报已界说过错,由于 SurFaceFlinger 模块的 Android.bp 已经界说了 LOG_Tag
//下面这样界说就不会出错了
#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "yuandaima_sf"
#endif
//打印仓库的头文件
#include <utils/CallStack.h>
//在 main 函数中打印信息
int main(int, char**) {
//打印日志
ALOGD("surfaceflinger is starting");
//打印仓库
android::CallStack callStack(LOG_TAG, 1);
//省掉后边的代码
//......
}
修正 /frameworks/native/services/surfaceflinger/Android.bp,添加 CallStack 的库依赖:
接着咱们从头编译代码,启动模拟器,进入 adb shell,检查 log:
rice14:/ # logcat | grep yuandaima_sf
05-11 09:54:10.291 1531 1531 D yuandaima_sf: surfaceflinger is starting
05-11 09:54:10.296 1531 1531 D yuandaima_sf: #00 pc 00000000000030a1 /system/bin/surfaceflinger (main+65)
05-11 09:54:10.296 1531 1531 D yuandaima_sf: #01 pc 000000000008a985 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+117)
经过 log 信息咱们能够知道程序的运行状态和运行过程中的要害参数。经过调用栈咱们能够知道函数的执行流程。
咱们还能够经过 Clion 来调试 C/C++ 代码:
这儿以调试 service_manager.c 为例:
咱们在如下位置打印好断点:
接着配置远程调试:
这样咱们的 Clion 就配置好了。
接着咱们检查 servicemanage 进程的 pid:
adb shell ps -A | grep servicemanager
system 1406 1 14116 5532 binder_ioctl 0 S servicemanager
system 1407 1 21764 9772 SyS_epoll_wait 0 S hwservicemanager
system 1408 1 14816 2584 binder_ioctl 0 S vndservicemanage
servicemanager 的 pid 为 1406,接着在模拟器上开启 gdbserver:
adb forward tcp:1235 tcp:1235
adb shell gdbserver64 :1235 --attach 1406
接着点击 Clion 右上角的 debug 按钮就进入 debug 环境了:
这样咱们就能够开始调试 C/C++ 代码了。
关于
假如你对 Framework 感兴趣或许正在学习 Framework,能够参阅我总结的Android Framework 学习道路指南,也可关注我的微信大众号,我会在大众号上继续共享我的经历,帮助正在学习的你少走一些弯路。学习过程中假如你有疑问或许你的经历想要共享给大家能够添加我的微信,我拉你进技术交流群。