Ubuntu 16.04环境下使用Clion 2019.1.4 gdb调试Android(安卓)7.1.2源码
转载请注明出处:https://blog.csdn.net/qq_43522781/article/details/95039848
一、调试环境
系统:Ubuntu 16.04
Clion:2019.1.4
Android:7.1.2_r36
gdb:7.11
二、调试准备
2.1 源码下载与编译
Android源码下载与编译请参见Android系统源代码的下载与编译(https://www.jianshu.com/p/aeaceda41798)
注意:编译时选择eng版本,我此次选择编译的项目为:aosp_x86-eng版本
2.2 源码编译常见问题
1、unsupported reloc 43错误:
cp /usr/bin/ld.gold /media/guoke/LENOVO/Android_srource/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/x86_64-linux/bin/ld
修改
/art/build/Android.common_build.mk
中的
# Host. ART_HOST_CLANG := falseifneq ($(WITHOUT_HOST_CLANG),true) # By default, host builds use clang for better warnings. ART_HOST_CLANG := trueendif
为:
# Host.ART_HOST_CLANG := falseifneq ($(WITHOUT_HOST_CLANG),false) # By default, host builds use clang for better warnings. ART_HOST_CLANG := trueendif
修改
/build/core/clang/HOST_x86_common.mk
在其中的
ifeq ($(HOST_OS),linux)CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS := \
下添加:
-B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin
结果为:
ifeq ($(HOST_OS),linux)CLANG_CONFIG_x86_LINUX_HOST_EXTRA_ASFLAGS := \ --gcc-toolchain=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG) \ --sysroot=$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/sysroot \ -no-integrated-as\ -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin
2、Try increasing heap size with java option ‘-Xmx’ 错误:
按照上述发现的提示语句,我们对prebuilts/sdk/tools/jack-admin文件进行如下修改:
首先找到如下语句:
JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -cp $LAUNCHER_JAR $LAUNCHER_NAME"
然后将上述语句修改为:
JACK_SERVER_COMMAND="java -XX:MaxJavaStackTraceDepth=-1 -Djava.io.tmpdir=$TMPDIR $JACK_SERVER_VM_ARGUMENTS -Xmx4096m -cp $LAUNCHER_JAR $LAUNCHER_NAME"
主要是添加了-Xmx4096m参数。
最后在源码目录下执行如下命令重启jack-admin服务:
./prebuilts/sdk/tools/jack-admin stop-server./prebuilts/sdk/tools/jack-admin start-server
重启完jack-admin服务后,此时再重新执行编译命令就能编译通过ninja了。
3、源码编译过程中卡死:
项目中遇到编译Android源码的过程中会卡住很久没有任何动静的情况,用top命令查看当前资源状态,发现是卡在aapt进程上面。
修改以下两个地方以后可以解决问题:
修改
build/target/product/languages_full.mk
和
build/target/product/locales_full.mk
中的
PRODUCT_LOCALES := en_US en_AU en_IN fr_FR it_IT es_ES et_EE de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN zh_HK ru_RU ko_KR nb_NO es_US da_DK el_GR tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN en_XA ar_XB fr_CA km_KH lo_LA ne_NP si_LK mn_MN hy_AM az_AZ ka_GE my_MM mr_IN ml_IN is_IS mk_MK ky_KG eu_ES gl_ES bn_BD ta_IN kn_IN te_IN uz_UZ ur_PK kk_KZ
为
PRODUCT_LOCALES := en_US zh_CN
2.3 Android Studio及Clion下载及安装
安装完成后,利用Android Studio的Avd Manager中下载API 25 的x86镜像并建立avd模拟器。模拟器运行成功后,将自己编译的镜像替换原始镜像进行运行检查。
具体:将out/target/product/generic_x86目录下的system.img、userdata.img、ramdisk.img复制到Sdk/system-images/android-25/google_apis_playstore/x86中,替换掉同名文件,并将其余无用文件删除,其中Sdk/为我的Android Studio sdk存放位置。替换后如下:
运行测试:
cd ~/Android/Sdk/tools./emulator -avd Nexus_5X_API_25
Build number中为我自己编译的版本,测试通过,可以继续开始下面的调试。
2.4、Clion中导入Android系统源码
由于Clion 仅支持Cmake,而Android采用的是Makefile 格式,因此需要参考Android Native C/C++ 使用CLion阅读/编译技巧
(https://blog.csdn.net/li864804994/article/details/79487834)
中的方式进行导入。
首先将下在后的android-cmake-project(https://github.com/Ahren-Li/android-cmake-project)文件拷贝到你的Android源码目录下。
然后导入源码,File→New Cmake Project From Source选择你的系统文件夹,后一路OK即可。
并修改env_android.cmake文件为:
set(ANDROID_LUNCH generic_x86)set(ANDROID_TARGET_ARCH x86)set(ANDROID_ABI "x86")#set(ANDROID_ABI "armeabi-v7a with NEON")#set(ANDROID_ABI "arm-v7")set(ANDROID_TOOLCHAIN_NAME "clang")set(ANDROID_STL c++_static)set(ANDROID_PLATFORM android-25)set(ANDROID_NATIVE_API_LEVEL 25)
然后修改设置如下:
注意:/media/u/LENOVO/Android_srource/修改为你自己路径。
等待Clion index完成。
如上,表示导入成功。
三、开始调试
3.1 使用gdb shell进行调试
这一步主要是为了测试调试文件及命令等是否正常,排除Clion以外的问题。
以调试init为例
在桌面新建一个文件夹,并在其中
新建run_emulator.sh文件
内容为:
cd ~/Android/Sdk/tools./emulator -avd Nexus_5X_API_25
新建start_android_gdb_server.sh(该文件在搭建Android源码调试环境(三)——调试C/C++(使用CLion)的基础上添加了部分调试信息)
#!/usr/bin/env bash gdbServerPid=`adb shell ps | grep gdbserver | awk '{print $2}'` echo "gdbserver进程Pid为: ${gdbServerPid} "if [[ "" != ${gdbServerPid} ]]; then adb shell su -c "kill ${gdbServerPid}"echo "Kill进程: ${gdbServerPid} "fiadb forward tcp:1234 tcp:1234 echo "端口转发成功,端口为:1234"if [[ `adb shell whoami` == 'root' ]]; then is_root=true echo "Shell为ROOT模式"fi if [[ -n $1 ]]; then appPid=`adb shell ps | grep ${1} | awk '{print $2}'` echo "要调试进程的Pid为: ${appPid}" if [[ -n ${appPid} ]]; then if [[ $is_root == true ]]; then adb shell gdbserver :1234 --attach ${appPid}echo "附加到进程 ${appPid} " else adb shell su -c "gdbserver :1234 --attach ${appPid} "echo "附加到进程 ${appPid} " fi else echo "$1 进程没有启动!" fi else echo "请设置要调试的进程名(app的进程名是包名)。例如 $0 " fi
新建gdb_shell_init文件
内容为:
shell adb forward tcp :1234 tcp :1234target remote localhost:1234file '/media/u/LENOVO/Android_srource/out/target/product/generic_x86/symbols/init'set sysroot '/media/u/LENOVO/Android_srource/out/target/product/generic_x86/symbols' set dir '/media/u/LENOVO/Android_srource' list
新建main_init.sh文件
内容为:
#!/usr/bin/env bash clion_pid=`ps -u | grep sh | grep clion.sh | awk '{print $2}'` if [[ "" == ${clion_pid} ]]; then cd ~/桌面/clion-2019.1.4/bingnome-terminal -x bash -c "sh clion.sh;"echo "启动clion: ${clion_pid} "read -p "clion是否启动完成" varfiecho "clion已启动完成。"cd ~/桌面/run_emulatoremulator_pid=`ps -u | grep emulator | grep Nexus_5X_API_25 | awk '{print $2}'` if [[ "" == ${emulator_pid} ]]; then gnome-terminal -x bash -c "sh run_emulator.sh;"echo "启动模拟器: ${emulator_pid} "read -p "模拟器是否已启动完成。" varfiecho "模拟器已启动完成。"cd ~/Android/Sdk/platform-tools./adb shell getenforce./adb shell "echo 0 > /sys/fs/selinux/enforce"while truedoecho "停止zygote运行。"./adb shell stop zygotezygote_pid=`adb shell ps | grep zygote | awk '{print $2}'`cd ~/桌面/run_emulator#gnome-terminal -x bash -c "./start_android_gdb_server.sh zygote;"gnome-terminal -x bash -c "./start_android_gdb_server.sh init;"read -p "gdbserver是否启动完成。" varcd /media/u/LENOVO/Android_srource/prebuilts/gdb/linux-x86/bin/echo "在clion中下断点,并运行调试。"#./gdb --command=~/桌面/run_emulator/gdb_shell_zygote./gdb --command=~/桌面/run_emulator/gdb_shellread -p "gdb是否已连接上远程gdbserver。" varcd ~/Android/Sdk/platform-toolsecho "开始运行zygote。"./adb shell start zygoteread -p "是否继续." varold_win_pid=`ps -u | grep start_android_gdb_server.sh | grep zygote | awk '{print $2}'` kill ${old_win_pid}done
其中
~/桌面/clion-2019.1.4/为我的Clion安装目录,
~/Android/Sdk/为我的sdk目录,
/media/u/LENOVO/Android_srource/为我的android源码目录,
~/桌面/run_emulator/为我存放上述文件的目录。
在目录中运行main_init.sh
出现如下图,说明gdb连接成功,端口为1234
出现:
说明调试符号、源文件、系统镜像等没有问题,可以进行调试。
3.2 使用Clion进行调试
按照搭建Android源码调试环境(三)——调试C/C++(使用CLion)
(https://blog.csdn.net/lylwo317/article/details/86545130)进行,在system/core/Init/service.cpp中的Start()函数设置好断点,
并设置Run/Debug Configurations如下:
其中注意:
gdb为android源码中的gdb
特别注意设置Path mappings,否则Clion会出现找不到源代码的情况。
设置Sysroot,让Clion可以找到符号文件
Symbool file,根据自己许调试的文件进行修改
设置完成后,在上面的脚本文件夹中新建main.sh文件,内容为:
#!/usr/bin/env bash clion_pid=`ps -u | grep sh | grep clion.sh | awk '{print $2}'` clion_pid_num=`ps -u | grep sh | grep clion.sh | wc -l` if [[ "1" == ${clion_pid_num} ]]; then cd ~/桌面/clion-2019.1.4/bingnome-terminal -x bash -c "sh clion.sh;"echo "启动clion: ${clion_pid} "read -p "clion是否启动完成" varfiecho "clion已启动完成。"cd ~/桌面/run_emulatoremulator_pid=`ps -u | grep emulator | grep Nexus_5X_API_25 | awk '{print $2}'` if [[ "" == ${emulator_pid} ]]; then gnome-terminal -x bash -c "sh run_emulator.sh;"echo "启动模拟器: ${emulator_pid} "read -p "模拟器是否已启动完成。" varfiecho "模拟器已启动完成。"cd ~/Android/Sdk/platform-tools./adb shell getenforce./adb shell "echo 0 > /sys/fs/selinux/enforce"while truedoecho "停止zygote运行。"./adb shell stop zygotecd ~/桌面/run_emulatorgnome-terminal -x bash -c "./start_android_gdb_server.sh init;"read -p "gdbserver是否启动完成。" varcd /media/u/LENOVO/Android_srource/prebuilts/gdb/linux-x86/bin/echo "在clion中下断点,并运行调试。"#./gdb --command=~/桌面/run_emulator/gdb_shellread -p "gdb是否已连接上远程gdbserver。" varcd ~/Android/Sdk/platform-toolsecho "开始运行zygote。"./adb shell start zygoteread -p "是否继续." varold_win_pid=`ps -u | grep start_android_gdb_server.sh | grep init | awk '{print $2}'` kill ${old_win_pid}done
后运行脚本
出现:
且clion中点击调试后在Console串口出现:Debugger connected to 127.0.0.1:1234
出现
在Debugger的GDB窗口出现:
说明,gdb连接正确,Clion能够正确加载符号文件和源码。
后按照脚本提示操作,回车后脚本恢复zygote运行,执行./adb shell start zygote命令。Clion中的源码中断在断点处,可以进行调试。
参考:
1、搭建Android源码调试环境(三)——调试C/C++(使用CLion)
(https://blog.csdn.net/lylwo317/article/details/86545130)
2、Android Native C/C++ 使用CLion阅读/编译技巧
(https://blog.csdn.net/li864804994/article/details/79487834)
3、Android系统源代码的下载与编译
(https://www.jianshu.com/p/aeaceda41798)
更多相关文章
- android 酷狗demo_高仿酷狗音乐播放器Android源码完整版
- Android(安卓)NDK 开发的栈错误调试
- android非常好的在线视频播放器源码(包含在线音频播放源码)
- 如何制作Jar包并在android中调用jar包
- Android(安卓)CTS 总结
- android SQLiteDatabase源码解析
- Logs in Android
- osg for android 学习之三:老外的步骤,包括编译和运行例子
- 【Android】播放视频的简易播放器源码