Linux搭建C开发环境
本篇文章基于WSL2 Ubuntu,使用CMake搭建 VSCode + C 的编译调试开发环境,本质上适用于所有Linux系统。
也可以从github上克隆示例项目[1]到本地,直接启动调试。
1.安装编译调试环境
1 | |
2.初始化工程结构
2.1 终端创建目录以及文件
1 | |
c_cpp_properties.json也可以通过VSCode自动生成: 在VSCode中Ctrl + Shift + P调出控制命令台,输入并选择C/C++ Edit Configurations(JSON),VSCode会自动生成合法的配置。
2.2 打开VSCode工作区
1 | |
2.3 复制内容到对应文件
1 | |
1 | |
1 | |
1 | |
1 | |
2.4 工程目录结构参考
以上准备工作结束后,工程的目录结构如下图所示,其中
include文件夹放置头文件,例如:sha256.hsource文件夹放置源文件,例如:sha256.c

3.编译调试
F7编译,F5启动调试(F5包含编译的过程),按照launch.json的StopAtEntry:true的定义,程序应该暂停在main
4.调试入门
所有语言以及IDE在调试的逻辑上基本是一致的,甚至连调试的快捷键也可能相同。比如MDK和VSCode的调试快捷键完全相同,虽然两者完全不具备可比性。VSCode官方介绍的Debugging用法[2]。
4.1 断点
断点作为调试中最重要的功能,常用的有三种,普通断点、条件断点和日志断点
4.1.1 普通断点
在一行语句上创建断点,启动调试后,程序会在该语句前暂停,即断点所在的行未被执行。以下图为例,程序执行到该断点处,b的值为0,说明语句b = debug_func(a);未被执行。继续往下执行,则b的值变为45,说明语句执行了。
4.1.2 条件断点
Conditional Breakpoint,条件断点,当程序符合预设的条件时,暂停在断点处,其标志是断点符号中有个等号。条件断点一般有两种情况,符合表达式或者命中次数。命中次数可以简单理解为该语句执行了多少遍。以下图为例,创建一个条件断点,Expression表达式i > 5与Hit Count命中次数5是等价的。

GDB调试器不一定支持Hit Count断点,启动调试后提示Breakpoints of this type are not supported by the debugger,该断点退化成普通断点。
增加一个变量,统计函数的运行次数,使用Expression的条件断点能够达到与Hit Count一样的效果。
4.1.3 记录点
当程序不方便暂停调试时,可以添加记录点,或者叫Logpoint。其符号是方块形状,在DEBUG CONSOLE控制台输出日志。如果称其为日志断点则不是很合适,因为程序没有暂停运行,不符合断点的概念
4.1.4 内联断点
内联断点,即Inline Breakpoint,用于调试一行代码中包含多个语句的情况。以下图为例,在for循环语句中,虽然只有一行代码,但是该行包含了3个语句:int i = 0和i < a以及i++。因此内联断点需要在指定的列前添加并显示。
在实际的工程项目中,如果工程遵守合理的编码规范的情况下,内联断点是基本用不上的。

4.1.5 函数断点
创建函数断点:选择Run->New Breakpoint->Function Breakpoint,输入函数的名称,断点创建成功。该方式可以但没必要,不如直接在函数的入口打一个普通断点来的方便。
4.2 监控变量
4.2.1 基础变量
Watch窗口可以查看所有类型的变量
- 数值类变量
int,float,double - 字符类型,先显示十进制的数值再显示
ASCII对应的字符 - 字符串(本质上是字符串指针),先显示地址再显示字符串的值
- 自定义的结构体以及枚举,枚举会显示枚举名称

4.2.2 不同进制
以int变量a为例,a默认以十进制的值显示,a,h以十六进制显示, a,b二进制,a,o八进制
4.2.3 表达式
监控变量窗口可以直接计算出表达式的结果
4.2.4 指针
如果监控一个void类型的指针,监控窗口只会显示指针地址,使用强制类型转换才能正确显示字符串或结构体或数组的具体值。下图展示void类型的指针转换为字符串指针或者结构体指针用法
强转数组则有一点区别,因为只强转数组的类型是不够的,还需要指定长度。假设需要强制指针array_ptr成长度为10的int数组,则表达式如下
1 | |

4.3 调用堆栈
以一个递归为例子,从1累加到5,预期进入5次递归函数。左侧的CALL STACK就会显示当前程序的调用栈。切换栈的深度时,观察arg的值

4.4 快捷键
熟练常用的调试快捷键非常重要,在实际项目中的效率远高于按钮点击的方式。
| 快捷键 | 英文 | 中文 | 描述 |
|---|---|---|---|
F5 |
Continue | 继续 | 继续运行到下一个断点 |
F10 |
Step Over | 单步跳过 | 执行一行代码 |
F11 |
Step In | 单步执行 | 进入函数 |
Shift + F11 |
Step Out | 单步停止 | 跳出函数 |
F9 |
Toggle Breakpoint | 切换断点 | 添加或者删除断点 |
F5

F10

F11

Shift + F11

5.导入C文件
根据当前的CMake规则,所有在include和source文件夹下的C文件会自动加入编译链接。以导入sha256库[4]为例子,计算一个从1到10的数组的哈希值
1 | |

使用在线哈希计算工具验证计算结果[5]。

6.终端编译运行
1 | |
6.1 测试结果
