目录

使用Visual Studio Code阅读和调试Android native代码

工欲善其事,必先利其器,这里记录下如何使用vscode去高效的阅读Android native代码

第一部分:c/c++配置

安装vscode

下载vscode安装包

这里贴一下Ubuntu上的安装步骤

1
2
3
4
5
$ # Ubuntu 20.04+版本,可以使用apt命令进行安装
$ sudo apt install ./code_xxx.deb
$
$ # Ubuntu 20.04-,则需要执行dpkg命令安装deb文件,并使用apt-get安装依赖
$ sudo dpkg -i ./code_xxx.deb && sudo apt-get install -f

安装C++的language server:clangd或ccls

clangd是llvm官方开发的language server,但在某些场景下的使用体验不如私人维护的ccls,所以如果你PC系统是Ubuntu20.04+的话,更推荐ccls;较低版本的Ubuntu系统安装ccls可能比较繁琐,使用clangd也还不错。

1
$ sudo apt install clangd # 或在ubuntu 20.04+版本上,sudo apt install ccls

安装vscode的clangd插件或ccls插件

打开vscode,参考图示搜索并安装clangd或ccls插件

clangd/ccls插件是vscode和clangd/ccls之间的桥梁

安装cmake

1
sudo apt install cmake

下载Android源码

这一部分跳过,由于GFW的原因,推荐大家参考https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/进行下载

生成compile db文件

编译Android源码 (dry-run)

1
2
3
4
5
6
7
8
$ source build/envsetup.sh
$ lunch xxx # 根据你自己的需要选择要lunch的目标
$ export SOONG_GEN_CMAKEFILES=1
$ make nothing
... # 编译主机的性能差异,这里可能要等待10~20分钟不等
$ ls -l out/development/ide/clion #查看生成的cmake配置文件
art     bootable  cmake-build-debug  cts     development  external    hardware  libnativehelper  packages          
bionic  build     CMakeLists.txt  ...

配置CmakeList.txt

我们通常只关心Android里的某些特定模块的代码,所以可以修改out/development/ide/clion/CMakeLists.txt
在里面添加关注的模块即可,这样就clangd/ccls就不用对所有的源码文件都进行索引了,查询和代码跳转都可以更快
例如以下是我的配置

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
cmake_minimum_required(VERSION 3.6)
project(qcom-v)
# To generate compile_commands.json
# set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# To generate compile_commands.json based this config, run the following command
# cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .

# 这里要改成你的源码路经,
set(ANDROID_ROOT /path-to-your-aosp-code-path)

# art
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/dex2oat/dex2oat-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/oatdump/oatdump-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/disassembler/libart-disassembler-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/dex2oat/libart-dex2oat-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/runtime/libart-runtime-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/profman/profman-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/libprofile/libprofile-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/sigchainlib/libsigchain-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/libartbase/libartbase-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/artd/artd-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/art/compiler/libart-compiler-arm64-android/)

# surfaceflinger and its deps
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/gui/libgui-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/ui/libui-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/ui/libui-types-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/renderengine/librenderengine-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/skia/libskia_renderengine-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/skia/libskia-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/CompositionEngine/QtiExtension/libqticompositionengineextension-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/CompositionEngine/libcompositionengine_test-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/CompositionEngine/libcompositionengine-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/CompositionEngine/libcompositionengine_mocks-arm64-android/)

add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/surfaceflinger-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/QtiExtension/libqtisurfaceflingerextension-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/layerproto/liblayers_proto-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/sysprop/libSurfaceFlingerProperties-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/FrameTimeline/libframetimeline-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/Scheduler/libscheduler_test-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/Scheduler/libscheduler-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/libSurfaceFlingerProp-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/surfaceflinger/libsurfaceflinger-arm64-android/)

# inputflinger
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/inputflinger/libinputflinger-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/inputflinger/libinputflinger_base-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/input/libinput-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/inputflinger/dispatcher/libinputdispatcher-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/services/inputflinger/reader/libinputreader-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/vendor/xiaomi/frameworks/native/services/inputflinger/libmiinputflinger-arm64-android/)

# installd
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/cmds/installd/installd-arm64-android/)

# libandroid_runtime
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/core/jni/libandroid_runtime-arm64-android)

# 其他
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/libs/androidfw/libandroidfw-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/libs/input/libinputservice-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/libs/services/libservices-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/cmds/app_process/app_process-arm64-android)

# services
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/base/services/core/jni/libservices.core-arm64-android/)

# vold
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/vold/vold-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/vold/libvold_binder-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/vold/libvold-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/vold/vdc-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/vold/vold_prepare_subdirs-arm64-android/)

# malloc debug
# add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/malloc_debug/libc_malloc_debug-arm64-android)
# add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/malloc_debug/libc_malloc_debug_backtrace-arm64-android)

# linker
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/linker/ld-android-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/linker/liblinker_main-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/linker/liblinker_malloc-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/linker/linker-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/linker/liblinker_debuggerd_stub-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libdl/libdl_android-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libdl/libdl_static-arm64-android/)

# libc
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/libc_bionic-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/libstdc++-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/async_safe/libasync_safe-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libc/system_properties/libsystemproperties-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/bionic/libfdtrack/libfdtrack-arm64-android/)

add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/init/init_second_stage-arm64-android/)

# libutils
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/libutils/libutils-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/libutils/libutilscallstack-arm64-android/)

add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/libcutils/libcutils-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/libbase/libbase-arm64-android/)

# binder
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/binderdebug/libbinderdebug-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/frameworks/native/libs/binder/libbinder-arm64-android)

# hwbinder
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/libhwbinder/libhwbinder-impl-internal-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/hwservicemanager/hwservicemanager-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/hwservicemanager/libhwservicemanager-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/libhidl/libhidlbase-arm64-android/)

# libc++
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/libcxx/libc++_static-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/libcxx/libc++experimental-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/libcxx/libc++fs-arm64-android/)

# debugugerd
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/crash_dump-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/debuggerd-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libdebuggerd_handler-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libtombstoned_client-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libdebuggerd_client-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libdebuggerd-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libdebuggerd_handler_core-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/tombstoned-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/libtombstoned_client_static-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/crasher/static_crasher-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/core/debuggerd/crasher/crasher-arm64-android/)

# unwind
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/unwinding/libunwindstack/libunwindstack-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/unwinding/libunwindstack/unwind-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/unwinding/libunwindstack/unwind_symbols-arm64-android/)

# lmkd
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/memory/lmkd/liblmkd_utils-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/memory/lmkd/libpsi/libpsi-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/memory/lmkd/lmkd-arm64-android/)

# suspend hal
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/hardware/interfaces/suspend/1.0/default/android.system.suspend-service-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/hardware/interfaces/suspend/1.0/default/libSuspendProperties-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/hardware/interfaces/suspend/1.0/android.system.suspend@1.0-arm64-android/)

# selinux
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/selinux/libselinux/libselinux-arm64-android/)

add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/apex/apexd/libapexd-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/apex/apexd/libapex-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/apex/apexd/apexd-arm64-android/)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/system/apex/apexd/libapexservice-arm64-android/)

# perfetto
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/perfetto/heapprofd-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/perfetto/libperfetto-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/perfetto/heapprofd_client-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/perfetto/trigger_perfetto-arm64-android)
add_subdirectory(${ANDROID_ROOT}/out/development/ide/clion/external/perfetto/perfetto-arm64-android)

上面我加的这些模块都是Android.bp里声明的cc_library[shared/static]或cc_binary的模块

注意
这里需要对Android源码的Android.bp的格式有一定了解,这部分不做介绍

生成compile_commands.json

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 我们感兴趣的模块里可能有aidl文件,那就要先编译这些模块以生成binder接口的.h和.cpp文件
# 否则会出现依赖会,导致生成compile_commands.json时出错
# 例如我这里添加了vold的,vold里有好几个aidl文件,所以要编译下vold
$ make vold...

$ ln -s out/development/ide/clion/CMakeLists.txt .
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .
# 如果这一步报错,根据错误提示继续make缺失的模块即可

$ ls -lh compile_commands.json # 查看生成的json文件
-rw-rw-r-- 1 pip pip 15M Oct 23 18:25 compile_commands.json

compile_commands.json里就包含了CmakeList.txt里的各个模块中源码文件的编译配置

打开VScode浏览源码

打开AndrodRuntime.cpp文件,能看到底部状态栏的clangd开始索引源文件了

clangd的索引速度还是不错的,当前打开的文件中的符号(头文件,变量,类,函数等)立即就可以(使用Ctrl + 鼠标左键)进行跳转了

ccls优势

注意
clagnd还是ccls都和vscode官方的c/c++插件有冲突,如果启用ccls或clangd中的任意一个,最好把另外2个都停用掉

如果是使用的ccls的话,我们还可以看到类/成员变量/函数被引用的情况,例如

可以看到在calculate_tree_size函数在22个地方被使用了,我们还可以点击“22 refs”,快速查预览这22个地方的代码,例如

ccls甚至还可以显示子类中某个函数被其他地方通过其父类指针调用的情况,例如:

若我们点击上图中的"1 b.ref",则可以看到dump函数被Binder.cpp里调用了

第二部分:rust配置

阅读资料:
Google使用rust开发底层系统库背后的原因
微软:we-need-a-safer-systems-programming-language
微软:why-rust-for-safe-systems-programming

安装vscode rust-analyzer插件

跟上面clangd和ccls插件一样的步骤,这里就不截图了

安装rustup工具

1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

生成rust项目的编译数据库

在SOONG_GEN_CMAKEFILES的基础上,增加SOONG_GEN_RUST_PROJECT

1
2
3
$ export SOONG_GEN_RUST_PROJECT=1 && export SOONG_GEN_CMAKEFILES=1
$ make nothing
$ cp out/soong/rust-project.json .

rust-project.json就和上面的compile_commands.json文件一样,包含了所有的rust代码的编译配置

启用

修改源码根目录下的vscode 配置文件

1
2
3
4
5
6
$ cat ./.vscode/settings.json
{
  "rust-analyzer.linkedProjects": [
    "rust-project.json"
  ]
}

参考以上配置,在"rust-analyzer.linkedProjects"里指明rust-project.json文件的位置

重启vscode,浏览rust代码

C++代码调试

向手机上push lldb-server

1
2
3
4
5
# 先要root一下手机
adb root

adb push prebuilts/clang/host/linux-x86/clang-r[最新版本]/runtimes_ndk_cxx/aarch64/lldb-server /data/local/tmp/arm64-lldb-server
adb shell chmod +x /data/local/tmp/arm64-lldb-server

启动lldb-server

1
2
3
4
5
6
7
# 先设置一下adb端口转发,把电脑的5039端口收到的数据转发给手机的/data/local/tmp/debug_socket
adb forward tcp:5039 localfilesystem:/data/local/tmp/debug_socket

# attach到我们要调试进程的installd进程,并监听debug_socket上来自lldb的请求
adb shell rm /data/local/tmp/debug_socket;
adb shell /data/local/tmp/arm64-lldb-server gdbserver \
         unix:///data/local/tmp/debug_socket --attach $(adb shell pidof installd)

此时如果我们再新打开一个终端,查看installd进程的状态,就会发现installd已经处于ptrace_stop状态了

1
2
adb shell ps | ag installd
root         18290     1   11007656   7104 ptrace_stop         0 t installd

开始调试

在vscode里调试

安装CodeLLDB插件

进入插件列表,搜索安装

codelldb.png

配置调试启动参数

配置Android源码目录下的.vscode/launch.json文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
    "configurations": [
        {
            "name": "Attach installd (port: 5039)",
            "type": "lldb",
            "request": "custom",
            "relativePathBase": "/home/wwm/aosp",
            "sourceMap": {
                "/b/f/w": "/home/wwm/aosp",
                "": "/home/wwm/aosp",
                ".": "/home/wwm/aosp"
            },
            "initCommands": [
                "settings append target.exec-search-paths /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/ /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/hw /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/ssl/engines /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/drm /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/egl /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/soundfx /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/ /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/hw /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/egl /home/wwm/aosp/out/target/product/ssi/symbols/apex/com.android.runtime/bin"
            ],
            "targetCreateCommands": [
                "target create /home/wwm/aosp/out/target/product/ssi/symbols/system/bin/installd",
                "target modules search-paths add / /home/wwm/aosp/out/target/product/ssi/symbols/"
            ],
            "processCreateCommands": [
                "gdb-remote 5039"
            ]
        }
    ]
}

我们这里attach的进程是installd,所以在targetCreateCommands里第一条就要选择带有debug符号表的installd文件路径
如果调试的是App进程的话,就要换成out/target/product/ssi/symbols/system/bin/app_process64了

启动调试UI

vscode-launch-debugger-ui.png

我们可以先设置几个断点,不出意外,就能看到下面这种调试UI啦! vscode-debugger-ui.png

也可以在底部的"debug console"可以直接输入各种lldb调试命令

在命令行里调试

如果不喜欢用vscode的调试界面,当然我们也可以在直接在终端里进行调试

准备lldb_setup_command.txt
1
2
3
4
5
6
7
8
9
# lldb_setup_command.txt内容
# 请根据你PC上symbols文件和源代码目录进行相应的修改
settings append target.exec-search-paths /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/ /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/hw /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/ssl/engines /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/drm /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/egl /home/wwm/aosp/out/target/product/ssi/symbols/system/lib64/soundfx /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/ /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/hw /home/wwm/aosp/out/target/product/ssi/symbols/vendor/lib64/egl /home/wwm/aosp/out/target/product/ssi/symbols/apex/com.android.runtime/bin
target create /home/wwm/aosp/out/target/product/ssi/symbols/system/bin/app_process64
settings append target.source-map '/b/f/w' '/home/wwm/aosp'
settings append target.source-map '' '/home/wwm/aosp'
target modules search-paths add / /home/wwm/aosp/out/target/product/ssi/symbols/
# If the below `gdb-remote` fails, run the command manually, as it may have raced with lldbserver startup.
gdb-remote 5039
启动lldb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
prebuilts/clang/host/linux-x86/clang-r522817/bin/lldb.sh -o 'command source -s 0 /home/wwm/aosp/lldb_setup_command.txt'

# lldb就会开始执行lldb_setup_command文件里定制的命令:
#  里面主要是告诉lldb去搜加载源码和去哪加载symbol文件,最后连到第2步里的lldb-server上
(lldb) command source -s 0 /home/wwm/aosp/lldb_setup_command.txt
(lldb) target create /home/mi/Downloads/health/out/target/product/ssi/symbols/system/bin/app_process64
Current executable set to '/home/mi/Downloads/health/out/target/product/ssi/symbols/system/bin/app_process64' (aarch64).
(lldb) settings append target.source-map '/b/f/w' '/home/wwm/aosp'
(lldb) settings append target.source-map '' '/home/wwm/aosp'
(lldb) target modules search-paths add / /home/mi/Downloads/health/out/target/product/ssi/symbols/
# 连接到5039端口,lldb-server收到后就会暂停被调试的进程
(lldb) gdb-remote 5039
Process 28067 stopped
* thread #1, name = 're-initialized>', stop reason = signal SIGSTOP
    frame #0: 0x0000007bcc12af2c libc.so`__ioctl at syscalls-arm64.S:776
   773             mov     x8, __NR_ioctl
   774             svc     #0
   775         
-> 776             cmn     x0, #(MAX_ERRNO + 1)
   777             cneg    x0, x0, hi
   778             b.hi    __set_errno_internal
   779         
   ...
(lldb) # 现在你可以在这里执行lldb各种调试命令了