0%

了解你的vscode

前言

对于利用vscode进行代码开发和调试我需要补充一些新的知识

了解 {} launch.json

launch.json是什么?

在 Visual Studio Code (VS Code) 中,launch.json 是一个用于配置调试会话的重要文件。它定义了如何启动和配置调试器,以及代码在调试过程中的行为。无论你是在本地开发环境还是远程服务器上进行调试,launch.json 都是一个关键的配置文件,能够帮助你更加高效地进行代码调试。

我没有这个文件应该如何获得?

创建launch.json文件后可以打开文件的编辑界面在右下角找到添加配置选择你想要添加的配置你就会获得一个基础的launch.json(其他两个文件同理)

其中的内容有什么含义?

其中生成的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
26
27
28
29
30
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},

],
"preLaunchTask": "C/C++: g++ 生成活动文件",
"miDebuggerPath": "/usr/bin/gdb",
}
]
}

其中每个key的功能如下:

键名 (Key) 类型 功能描述 示例值/选项 重要性
name string 配置项在调试器下拉菜单中的显示名称 "(gdb) 启动" ⭐⭐⭐⭐
type string 指定调试器类型 "cppdbg" (C++调试) ⭐⭐⭐⭐⭐
request string 调试启动类型 "launch" (启动程序) 或 "attach" (附加进程) ⭐⭐⭐⭐
program string 被调试程序路径 ${fileDirname}/${fileBasenameNoExtension} ⭐⭐⭐⭐⭐
args array 传递给程序的命令行参数 ["--param=value", "input.txt"] ⭐⭐⭐
stopAtEntry boolean 是否在 main 函数入口暂停 true (暂停)/false (不暂停) ⭐⭐⭐⭐
cwd string 程序工作目录 ${fileDirname} (当前文件目录) ⭐⭐⭐⭐
environment array 设置环境变量 [{"name": "PATH", "value": "/custom/bin"}] ⭐⭐
externalConsole boolean 是否使用外部终端 true (外部)/false (VSC内置终端) ⭐⭐⭐
MIMode string 指定调试引擎 "gdb" (GNU调试器) ⭐⭐⭐⭐⭐
setupCommands array gdb 初始化命令 -enable-pretty-printing (结构化输出) ⭐⭐⭐
preLaunchTask string 调试前执行的任务 "C/C++: g++ 生成活动文件" (编译任务) ⭐⭐⭐⭐
miDebuggerPath string gdb 调试器路径 "/usr/bin/gdb" ⭐⭐⭐⭐⭐

关键路径变量说明:

  • ${fileDirname}:当前打开文件所在目录
  • ${fileBasenameNoExtension}:当前文件名(不含扩展名)
  • ${workspaceFolder}:VSCode 打开的工作区根目录

使用技巧:

  1. 单文件调试
    program 使用 ${fileDirname}/${fileBasenameNoExtension} 可直接调试当前打开的文件

  2. ROS节点调试

    1
    2
    "program": "${workspaceFolder}/devel/lib/pkg_name/node_name",
    "args": ["_param:=value"]
  3. 添加条件断点
    1
    2
    "text": "break main if argc > 1",
    "ignoreFailures": false
  4. 添加ros环境
    1
    2
    3
    4
        "environment": [{
    "name": "ROS_MASTER_URI",
    "value": "http://localhost:11311"
    }]

    tasks.json是什么?

使用不同的编程语言可能有不同的开发流程,比如 C/C++ 就需要编译(广义编译,包括了链接)、运行、测试、打包等等流程,而 Python 只需要运行即可,为了把各种语言的不同开发流程抽象成同一套流程,于是有了编码(Code)— 构建(build)— 运行/调试(run/debug)— 测试 (test) — 打包(package) 等等,其中每个环节都可以认为是一个 task,所以可以利用 tasks.json来手动完成那些使用 IDE 时被隐藏的开发流程细节

其中的内容有什么含义?

其中代码如下:

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
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ 生成活动文件",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}

键名 (Key) 类型 功能描述 示例值/选项 重要性
type string 任务类型 "cppbuild" (C++编译任务) ⭐⭐⭐⭐
label string 任务标识符 "C/C++: g++ 生成活动文件" ⭐⭐⭐⭐⭐
command string 编译器路径 "/usr/bin/g++" ⭐⭐⭐⭐⭐
args array 编译参数 ["-fdiagnostics-color=always", "-g", ...] ⭐⭐⭐⭐
options.cwd string 编译时的工作目录 "${fileDirname}" (当前文件目录) ⭐⭐⭐
problemMatcher array 错误匹配器 ["$gcc"] (GCC错误格式) ⭐⭐⭐
group.kind string 任务分组类型 "build" (构建任务) ⭐⭐⭐
group.isDefault boolean 是否为默认构建任务 true (是默认任务) ⭐⭐⭐⭐
detail string 任务描述信息 "调试器生成的任务。"

编译参数 (args) 详解:

参数 功能说明 重要性
-fdiagnostics-color=always 启用彩色错误输出 ⭐⭐⭐
-g 生成调试信息 ⭐⭐⭐⭐⭐
${file} 当前活动文件 ⭐⭐⭐⭐⭐
-o 指定输出文件名 ⭐⭐⭐⭐
${fileDirname}/${fileBasenameNoExtension} 输出文件路径 ⭐⭐⭐⭐⭐

常用扩展参数:

1
2
3
4
5
6
7
8
"args": [
"-Wall", // 开启所有警告
"-Wextra", // 启用额外警告
"-O0", // 禁用优化(调试时推荐)
"-I${workspaceFolder}/include", // 添加头文件路径
"-L${workspaceFolder}/lib", // 添加库文件路径
"-lmy_library" // 链接指定库
]

c_cpp_properties.json的功能

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
键名 (Key) 类型 功能描述 示例值/选项 重要性
name string 配置名称 "Linux" (平台标识) ⭐⭐⭐
includePath array 头文件搜索路径 ["${workspaceFolder}/**"] ⭐⭐⭐⭐⭐
defines array 预处理器宏定义 ["DEBUG", "VERSION=1.0"] ⭐⭐⭐
compilerPath string 编译器路径 "/usr/bin/gcc" ⭐⭐⭐⭐⭐
cStandard string C语言标准版本 "c17" (C17标准) ⭐⭐⭐
cppStandard string C++语言标准版本 "gnu++14" (GNU C++14标准) ⭐⭐⭐⭐
intelliSenseMode string IntelliSense 引擎模式 "linux-gcc-x64" (Linux+GCC+x64) ⭐⭐⭐⭐
version number 配置文件版本 4

关键配置说明:

  1. includePath

    • ${workspaceFolder}/**:包含工作区所有子目录
    • 添加ROS路径:"/opt/ros/noetic/include/**"
  2. cppStandard 选项:

    • c++11, c++14, c++17, c++20
    • GNU扩展版本:gnu++14
  3. intelliSenseMode 常用值:

    • linux-gcc-x64
    • windows-msvc-x64
    • macos-clang-x64

开始基础调试

执行编译

  • group中的isDefault: 值为true表示支持通过快捷键ctrl+shift+B来执行该编译任务。如果值改为false,也可以从菜单中选择运行:Terminal(终端)>Run Build Task(进行生成任务)。

生成结果如下,表示g++编译成功:
build

按+号创建一个新的在当前目录下的终端

newshell

同时可以输入ls查看发现多了一个相关的可执行文件,输入./filename你就可以运行这个文件了

runfile

执行编译遇到的问题

在编译包含外部库jsoncpp的cpp文件时出现了使用代码g++ readFromString.cpp -ljsoncpp -std=c++11 -o readFromString可以正常编译使用ctrl+shift+b却编译失败的问题

详细介绍一下g++ readFromString.cpp -ljsoncpp -std=c++11 -o readFromString:

命令部分 功能说明 详细解释 是否必需
g++ 调用编译器 GNU C++ 编译器的主程序 ✅ 必须
readFromString.cpp 指定源文件 要编译的 C++ 源代码文件 ✅ 必须
-ljsoncpp 链接 JSON 库 1. -l 表示链接库
2. jsoncpp 是 JSON 库的简称
3. 实际链接 libjsoncpp.so 文件
✅ 必须
-std=c++11 指定 C++ 标准版本 使用 C++11 语言特性进行编译 ⚠️ 推荐
-o 指定输出文件名 设置生成的可执行文件名称 ⚠️ 可选
readFromString 输出文件名称 编译后生成的可执行文件名(省略扩展名) ⚠️ 可选

感觉vscode编译功能失败的原因应该在tasks.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
26
27
28
29
30
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ 生成活动文件",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-ljsoncpp", // 必须包含库链接
"-std=c++11" // 必须包含标准版本
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}

问题成功解决!!!

执行调试

设置一下stopAtEntry

stopAtEntry: 默认情况下,C++拓展不会向源代码添加任何断点,stopAtEntry 值设置为 false。 将stopAtEntry值更改为 true 将使调试器在开始调试时停止在 main 方法上。

开始一个调试会话

在调试的程序页面按f5或者Run(运行) > Start Debugging(启动调试),用户界面的几个变化: 集成终端出现在源代码编辑器的底部,在“Debug Output”选项卡中,会看到指示调试器已启动并正在运行的输出。编辑器突出显示 main 方法中的第一条语句。这是 C++拓展自动设置的断点。

debug

使用箭头指出的工具进行调试:

  • 第一个是从断点开始继续进行程序

  • 第二个是逐步进行程序

  • 第三个是更细致的逐步进行

  • 第四个是重新启动

  • 第五个是停止

逐行执行代码时在debug下可以看到变量的值,同时可以在监管里点击+添加你要监控的变量,将鼠标直接放在变量上也会显示他的值:

debugwatch