使用 LLDB 在 VS Code 中调试 Android C_C++ 代码(无需 Android 源代码)
需求分析
在使用GDB在VS Code调试Android C/C++代码(无需Android源码)文章中介绍了如何在VS Code中使用GDB来调试Android C/C++代码,在浏览Android文档Using Debuggers中发现,文档更新了,不建议使用GDB
,应尽可能使用LLDB
(注意:查看Android文档时,在右上角语言选择ENGLISH
,才能浏览最新文档,而不是选择中文-简体
)。同样文档中介绍了如何基于Android源码,在VS Code中使用CodeLLDB extension进行调试,下面我们将探索如何在VS Code中不使用Android源码进行调试。
探索过程
官方文档说明
在上述Android文档Using Debuggers中介绍了如何使用LLDB调试。与之前GDB类似,它提到的前置条件是使用Android源码中gdbclient.py
或者lldbclient.py
(lldbclient.py
就是gdbclient.py
的软连接)脚本。此脚本会生成VS Code的配置文件,将其设置到launch.json
中,并在Android设备上启动lldb-server
,在主机上启动lldb,然后将lldb连接到远程的lldb-server。
前人使用记录
在LLDB调试Android Native程序中详细阐述了使用LLDB调试的过程。总结成下面几个核心步骤:
- 从NDK中获得获取对应的平台的lldb-server;
- 将lldb-server放入设备并启动:
./lldb-server p --server --listen unix-abstract:///data/local/tmp/debug.sock
;- 本机lldb连接远程lldb-server,调试方式分为两种:a、 launch:直接启动要调试的程序; b、 attach:将调试器附到可调试进程中。
那么如何在VS Code中使用LLDB呢,接下来我们实际操作一下。
来实践一下吧
先决条件
1、安装Visual Studio Code以及在其中安装CodeLLDB extension,安装后lldb在此路径下~/.vscode/extensions/vadimcn.vscode-lldb-1.6.1/lldb/bin/lldb
,在手动调试时候可以使用。
2、下载好Android NDK,方便使用其中lldb-server
,它在<NDK_ROOT>/android-ndk-r21b/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.8/lib/<Platform>/<Arch>目录下。Platform代指本机系统,Arch代指要调试的Android的ABI。
3、编译项目时,需要添加调试信息,即在Android.mk中添加LOCAL_CFLAGS += -g,或者通过在ndk-build命令行上传递NDK_DEBUG=1。同时如果项目的Application.mk文件指定APP_OPTIM设置,必须将其设置为debug以禁用编译器优化。
调试设置
1、VS Code中打开需要调试的项目,点击运行>>启动调试(或直接按F5快捷键)。
在弹出的窗口中选择LLDB
,若无此选项请检查CodeLLDB extension是否安装。
第一次没有配置文件时,会弹出如下窗口,点击确认
,将会在当前项目中.vscode中生成默认的launch.json
文件。
2、launch.json的设置属性如下所述。
name:调试配置的名字,在进行调试时,根据名字选择不同的配置。
type: 设置为"lldb",表示使用CodeLLDB extension
提供的lldb进行调试。
program:要调试的程序。这应该指向带有调试符号的可执行文件的本地版本(非剥离版本),通常在项目的构建目录下的obj/local/armeabi-v7a中(对于64位构建,则位于obj/local/arm64-v8a中)。
request:分为attach和launch。
preLaunchTask:在启动调试器之前要执行的任务。
initCommands:初始化时相关的参数。
更多相关信息,请参考 vscode-lldb/MANUAL.md。
示例launch.json文件:
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "attach",
"name": "lldb attach",
"program": "${workspaceFolder}/test",
"preLaunchTask": "lldb build task",
"initCommands": [
"platform select remote-android",
"platform connect connect://localhost:9090",
"settings set target.inherit-env false",
],
},
{
"type": "lldb",
"request": "launch",
"name": "lldb launch",
"program": "${workspaceFolder}/test",
"preLaunchTask": "lldb build task",
"initCommands": [
"platform select remote-android",
"platform connect connect://localhost:9090",
"settings set target.inherit-env false",
"platform settings -w /data/local/tmp/",
"platform status"
],
},
]
}
3、前面提到preLaunchTask任务,这些任务也可以用于支持调试。可以定义一个任务来编译代码,push程序到手机端,转发调试器端口等操作。
在.vscode中添加一个tasks.json文件。如下:
{
"version": "2.0.0",
"tasks": [
{
"label": "build task",
"type": "shell",
"command": "source debug.sh"
}
]
}
注意task中"label"的值和launch中"preLaunchTask"的值一致。这里我们执行一个shell命令,将具体的任务放在debug.sh中处理。有关任务配置的更多信息,请参见VSCode文档。
4、在项目中新建debug.sh文件,内容如下:
#!/bin/bash
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk APP_BUILD_SCRIPT=Android.mk clean
ndk-build NDK_DEBUG=1 NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk APP_BUILD_SCRIPT=Android.mk -j16
adb push obj/local/arm64-v8a/test /system/bin/
adb shell chmod 777 /system/bin/test
adb forward tcp:9090 tcp:9090
gnome-terminal -- bash -c "adb shell '/data/local/tmp/lldb-server platform --listen *:9090 --server'"
a、首先使用ndk-build编译代码,里面增加了NDK_DEBUG=1,使其生成的程序包含调试信息;再将生成的程序push到/system/bin/目录下,同时赋予可执行权限。
b、设置端口转发
在开发机上设置端口转发,命令如下:
adb forward tcp:9090 tcp:9090
命令说明:表示通过adb映射tcp端口1234,命令中前面的是local的端口,后面的是remote的端口。命令中的端口号必须与lldb-server命令中的监听端口号相同,否则会导致lldb无法与lldb-server连接。
c、在目标设备上执行lldb-server
adb shell "/data/local/tmp/lldb-server platform --listen '*:9090' --server &" &
更多介绍可以查看lldb官方文档The LLDB Debugger。
启动调试
一切准备ok,接下可以开始调试了,在选择配置时可以选择lldb attach
和lldb launch
,根据实际使用情况选择不同模式。
三种方式启动:
1、通过单击VS Code窗口左侧的Debug图标,启用“开始调试”面板;
2、从面板顶部的列表中选择“运行”,然后单击执行“启动调试”按钮;
3、直接快捷键F5。
一旦调试器开始连接,VSCode调试控制台将显示来自调试器的消息,并在必要时允许执行手动调试器命令(必须停止程序以执行调试命令)。调试面板将显示调试信息(变量监视,调用堆栈,断点等),调试器工具栏将提供对常见调试命令的访问。还支持基于鼠标光标的变量显示。
上一篇: LLDB 读取内存指令
下一篇: 您对 LLDB 了解多少?