转载请注明出处: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)

更多相关文章

  1. android 酷狗demo_高仿酷狗音乐播放器Android源码完整版
  2. Android(安卓)NDK 开发的栈错误调试
  3. android非常好的在线视频播放器源码(包含在线音频播放源码)
  4. 如何制作Jar包并在android中调用jar包
  5. Android(安卓)CTS 总结
  6. android SQLiteDatabase源码解析
  7. Logs in Android
  8. osg for android 学习之三:老外的步骤,包括编译和运行例子
  9. 【Android】播放视频的简易播放器源码

随机推荐

  1. Android(安卓)NavigationBar 代码分析记
  2. Android之简单的文件夹选择器实现
  3. Android(安卓)Activity生命周期以及onSav
  4. 设置android:elevation无效
  5. Android实现开机自启动Service
  6. Android(安卓)获取设备序列号(SN号)含源码D
  7. Android(安卓)ListView长按Item功能
  8. android 监听开机(关机)
  9. android GPRS
  10. Android(安卓)浅析 Volley (一) 使用