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++ 代码了。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/20522,转载请注明出处。
评论0