VScode 远程调试
前言
VScode 只是一个很简单的文本编辑器,如果你在使用 VScode 进行远程调试时,发现不能查看 STL 容器的值,请参见 GDB容器可视化, 这个问题将在这里被解决。
此外,这是只是提供一种解决方案而已,而非完美的解决方案,例如在 VScode 使用 Remote - SSH
或者说是 远程资源管理器
来辅助远程调试,无疑是一种更加有效便捷的方式;但是在我的目标机上,由于大部分的文件目录是只读的,加上目标机上的脚本只有 sh 而无 bash,所以 远程资源管理器
对我来说这个方案是不行的。
配置
要说到 VScode 配置远程调试,那自然就得说到 VScode 的配置了;我们常常说 Linux万物皆文件,C++万物可对象,那么对于 VScode 而言,我觉得 VScode 就是万物皆 json; VScode 的插件基本上都是基于 javascript 开发的,所以 json 自然而言就成为其配置的语言。
VScode 能否正常、方便地进行远程调试,很大程度上取决于你的配置文件写的如何了;与远程调试息息相关的配置文件在 VScode 里一共有 4 个,分别是 c_cpp_properties.json
、 launch.json
、 settings.json
以及 tasks.json
, 只要合理地配置这四个配置文件,一般来说 VScode 远程调试的体验感就已经挺好的了。
settings.json
这个文件一般是不用你操心的,它一般是自己就配置好的,以防万一还是给出一个默认的 settings.json
的配置,VScode 默认是不需要这个配置文件的,即使这个文件不在的情况下, VScode 仍然有默认配置,但是你可以使用这个文件去覆盖默认配置。
{
"files.associations": {
"cmath": "cpp",
"complex": "cpp",
"version.h": "c",
"namespace.h": "c",
"tc_common.h": "c",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"condition_variable": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"memory": "cpp",
"mutex": "cpp",
"new": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"thread": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"*.ipp": "cpp",
"strstream": "cpp",
"codecvt": "cpp",
"forward_list": "cpp",
"unordered_set": "cpp",
"algorithm": "cpp",
"iterator": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"regex": "cpp",
"rope": "cpp",
"slist": "cpp",
"future": "cpp",
"shared_mutex": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"valarray": "cpp",
"hash_map": "cpp",
"hash_set": "cpp"
},
"git.ignoreLimitWarning": true
}
c_cpp_properties.json
这个文件虽然跟远程调试没啥太大关系,但是没有配置好的话会让你使用 VScode 的体验感变得挺差,我个人觉得最重要。
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceRoot}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "gnu++11",
"intelliSenseMode": "linux-gcc-x64",
"browse": {
"path": [
"${workspaceRoot}/**"
],
"limitSymbolsToIncludedHeaders": true
},
"compileCommands": "",
"configurationProvider": "go2sh.cmake-integration"
}
],
"version": 4
}
需要注意的配置地方主要就是 includePath
以及 browse path
,这里关系到你可以可以友好地在头文件间之间相互跳转, ${workspaceRoot}
代表的你打开 VScode 时所选择的文件夹,也就是 VScode 的工作目录,而 **
则是递归搜索此目录下的所有文件夹作为头文件路径。
以下是一个简单的对比图:
值得一提的是,在我的项目里,我所有的头文件都是放在我的项目底下的,无论是第三方库还是我自己写的头文件,所以在我这里这么配置就可以了;除此之外,系统路径下的头文件是不需要自己的添加的。
launch.json
luanch.json
是调试 F5
的启动依赖,它的一个配置范例如下:
{
"version": "0.2.0",
"configurations": [
{
// 配置名称。显示在启动配置下拉菜单钟
"name": "web_tc(launch)",
// 配置类型
"type": "cppdbg",
// 请求配置类型,可以是 "launch" 或者 "attach"
"request": "launch",
// 程序可执行文件的完整路径
"program": "${workspaceRoot}/bin/web_tc",
// 传递给程序的命令行参数
// 逗号分隔每一个参数,注意这是 json 数组类型
"args": ["${workspaceRoot}/bin/config.json"],
// 是否停在 mian 函数
"stopAtEntry": true,
// 目标的工作目录
"cwd": "${workspaceRoot}",
// 环境变量引入
// 例如动态库路径 LD_LIBRARY_PATH 就可以在这里配置,替换你 export 的方案
"environment": [],
// 是否需要终端显示
"externalConsole": false,
// 控制台调试程序
"MIMode": "gdb",
// gdb 启动时的参数
"setupCommands": [{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}],
// 调试会话前开启的任务
"preLaunchTask": "complie",
// 调试程序路径,也就是 gdb 路径
"miDebuggerPath": "/home/haorui/tools/arm-hisiv600-linux-gdb/bin/arm-hisiv600-linux-gdb",
// gdb server 的地址
"miDebuggerServerAddress": "172.20.92.88:10020"
}
]
}
以上就是一个完整的 launch.json , 但是应该还不能满足你的需求,那么剩下的就要依赖 gdb 了,也就是 setupCommands
, 这个等下再说了。
注释写的挺清楚了,如果你不能理解 miDebuggerServerAddress
是在干什么,那么这是不属于这里的内容,你可以查查 gdb
与 gdbserver
结合远程调试方案,这里用命令行都可以进行调试。
值得需要注意就是 preLaunchTask
,这是一个在调试前需要执行的任务,你可以记录以下 complie
这个任务的名字,这是可以随意更改的,这要和 task.json
中保持一致即可。
tasks.json
给出一个范例:
{
"tasks": [
{
"type": "shell",
"label": "complie",
"command": "make",
"args": [
"-j8"
],
"options": {
"cwd": "${workspaceRoot}/build"
}
}
],
"version": "2.0.0"
}
这里一般其实并不是这么写的,这是这个环境下我只有这么一点点东西,其实建议把 command
写成一个脚本,这样就看也i DIY 行为了。
其他
其实 VScode 是很人性化的,对于 *.json
文件,也就是 VScode 的配置文件,鼠标悬停可以看到字段的解释,回车可以看到还可以选择的字段,如果对于上面的配置不清楚或者想自己探索的话,这是一种比较好的方法。