1. 简介
最近我意识到,调试是一个非常有用的手段。我记得我们当初学习 C 语言时,都是使用一个 IDE(比如 CodeBlocks、Dev-C ) 来进行编程和调试;然而随着学习的深入,我发现很多 Debug 工作直接用 printf
就能完成,还是自己接触的工作太少太简单,于是就没太学习调试这方面的知识;直到我开始尝试阅读一个比较大的项目源码。
一个大的项目源码,往往包含一堆的源代码、头文件、配置文件、脚本文件,它们往往又都是通过 Makefile 文件来进行组织维护的。虽然 Makefile 有写明编译的目标和其对应的依赖,但对于大项目来说,错综复杂的依赖关系即使去认真阅读 Makefile 文件也不是那么容易理清,更何况大项目的 Makefile 文件往往为了书写方便进行了大量封装,阅读起来实在困难。
而这时,调试的作用就体现出来了。调试不仅仅可以用来 Debug,我觉得更重要的是它能帮你理清一个程序它是从何而始、至何而终以及它整个执行路线是什么。这便是我这篇文章为什么要介绍配置调试环境的原因。
2. 配置
要让 VSCode 具备 C 的调试工能,首先需要安装 MicroSoft 官方的 C 工具插件,直接在扩展插件中搜索 C/C
即可找到。安装完后,需要进一步进行配置才能使用:
首先用 VSCode 打开你要调试的项目目录,然后可以看到左侧栏出现一个调试按键,点击一下会弹出如下提示:
这是告诉你目前没有任何的配置文件来供编译调试,这里点击 Create a launch.json file 创建一个新的配置文件。
注意,点击 Create a launch.json file 创建新的配置文件时,VSCode 主窗口要处在打开某一个 C 文件状态下,这样它才能自动识别你是要进行 C 项目的编译调试工作。 创建新的配置文件后,VSCode 会自动打开该 launch.json 文件:
你需要给出对应的配置参数才能开始进行编译调试。好在这个插件已经给出了一般的配置模板,点击 Add Configuration,VSCode 会询问我们要选择何种调试工具,Linux 上一般都预装了 gdb,所以我们就选 C/C : (gdb) Launch 即可。生成的配置模板大致如下所示:
代码语言:javascript复制{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
最后,我们只需要修改模板中相应的参数即可,主要是 "program" 和 "args" 字段。"program" 字段用来指定要调试的二进制可执行文件,"args" 用来指定传给二进制可执件文件的输入参数。完成这两项后,就可以开始基本的调试了。 如果你的项目只包含源代码,那么你需要先将源代码编译一遍。一般来说有 Makefile 文件的可以直接 make 编译,没有 Makefile 文件的可以找找是否有 CMakeLists 文件或者 Configure 脚本,然后使用它们生成 Makefile 文件后再 make 编译,在项目中的 README 中一般也会说明如何编译。不过编译时需要注意的是,确保 Makefile 文件中的 CFLAGS 和 CXXFLAGS 变量包含 -g 参数,如果没有则加上,-g 参数是为了保证编译出来的二进制文件包含调试信息(也即俗称的 Debug 版本二进制文件),这样我们才能使用调试工具进行调试。
附录
- C Tutorial for Beginners #10: Debugging Makefile Project with Visual Studio Code IDE | (Linux GDB)