1. 前言:为什么要折腾 WSL?
临近期末,复习C语言时实在是受不了Visual Studio复杂的操作(还没法直接写C),但是用VScode又被Windows的终端编码(GBK)搞的痛不欲生
听说Linux编程配环境很容易,但是又不想放弃Windows的娱乐优势,所以学习了WSL来平衡二者。
这篇文章记录了从简单的命令行到GDB调试的全过程,用于备忘。
2. 环境准备与基础命令
2.1 环境架构
- 系统: Windows 11 25H2 + WSL2 (我用的是 Ubuntu)
- 编译器: GCC
- 调试器: GDB
- 编辑器: VS Code
2.2 WSL 基础命令
在 PowerShell 中,可以用几个简单命令管理 WSL:
# 启动并进入默认的 Linux 发行版
wsl
# 查看已安装的发行版及其版本(最好用WSL2)
wsl -l -v
注意:从隔离的角度考虑,最好在在 Linux 的
/home/用户名目录下进行代码开发**,不要跨盘操作(如/mnt/c)。
几个高频使用的终端命令:
pwd # 确认当前路径
ls -l # 列出文件详细信息
cd ~ # 快速回到 /home 目录,这里~=/home/用户名
mkdir code # 创建项目文件夹,使用-p参数来递归创建文件夹
2.3 安装核心开发工具
刚装好的 Ubuntu 可能不带开发工具,需要手动安装 build-essential 包,它包含了 gcc, g++, make 等一系列开发必备工具。
sudo apt update
sudo apt install build-essential
3. GCC 和 GDB 常见命令与内部逻辑
在配置 IDE 之前,必须先熟练掌握底层的命令行逻辑。为了演示 GDB 的强大,我们先来写一段看似没问题但结果错误的代码。
3.1 这是一个有BUG的程序
创建一个名为 test.c 的文件,目的是计算 1 到 n 的和:
#include <stdio.h>
int main(){
int n;
int sum;
scanf("%d", &n);
for (int i = 1; i <= n; i++){
sum += i;
}
printf("%d\n", sum);
return 0;
}
3.2 编译器 (GCC) 的标准命令
不要只会用 gcc test.c,养成添加标准参数的习惯,这能帮你发现无数潜在的 Bug。
# 推荐的编译指令,参数详解:
# -g : 生成调试信息(GDB 调试必须加,否则看不到源码和变量名)
# -Wall : 开启所有警告(这对排查隐患至关重要)
# -std=c11 : 指定 C11 标准,可以更换
# -o demo : 指定输出的可执行文件名为 demo
gcc test.c -g -Wall -std=c11 -o demo
3.3 一个用GDB排除BUG的案例
以下,我将会模拟一场真实的BUG排查。
第一步:编译并启动调试
gcc test.c -g -o demo
gdb ./demo
第二步:打断点
我们希望程序停在 main 函数刚开始的地方,好让我们一步步观察。
(gdb) b main # b命令,打断点,支持按行数打断点
Breakpoint 1 at 0x1195: file test.c, line 3.
第三步:运行程序
(gdb) r # r命令,运行程序
Starting program: /home/yourname/code/demo
Breakpoint 1, main () at test.c:3
3 int main(){
此时,程序停在了第 3 行,还没执行。
第四步:单步执行与查看变量
这是最关键的一步。我们往下走几步,看看 sum 的值。
注意,GDB只会检查执行语句,变量声明会直接跳过(除非变量在声明时就进行了赋值操作,如 int n = 0;),所以就从第3行跳到了第6行。
(gdb) n
6 scanf("%d", &n);
(gdb) n
5 #输入n的值
8 for (int i = 1; i <= n; i++){
此时,sum 已经被声明,但还没进入循环。让我们看看现在 sum 里面是什么:
(gdb) p sum # p命令,打印变量值
$1 = -8944 # 发现是一个奇怪的值,说明是内存中的垃圾值
得出结论:因为没有初始化 sum = 0,它直接拿内存里的垃圾值去累加了,所以结果会不对。
第五步:退出 (Quit) 找到问题后,退出 GDB 去修改代码。
(gdb) q # q命令,退出调试
4.配置 VS Code 实现一键图形化调试
理解了上面的命令行全过程后,我们就可以通过配置让 VS Code 帮我们“代劳”,实现F5 一键图形化调试。
4.1 连接 WSL
- VScode必须安装 WSL 插件。
- 在 WSL 终端进入你的项目目录:
cd ~/code。 - 输入
code .启动 VS Code。 - 看到 VS Code 左下角显示
WSL: Ubuntu即表示连接成功。
4.2 配置 tasks.json (代替手工 GCC)
我们的目标是:按下 Ctrl+Shift+B 自动执行上面那串 gcc 编译命令。
在项目根目录创建 .vscode/tasks.json 文件,填入以下内容:
{
"version": "2.0.0",
"tasks": [
{
"label": "GCC Build Active File", // 任务标签,记注它,后面要用
"type": "shell",
"command": "/usr/bin/gcc",
"args": [
"-g", // 必须有,否则无法调试
"${file}", // 当前打开的文件名
"-o",
"${fileDirname}/${fileBasenameNoExtension}.out", // 输出为同名.out文件
"-std=c11",
"-Wall"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"]
}
]
}
4.3 配置 launch.json (代替手工 GDB)
我们的目标是:按下 F5,自动调用上面的编译任务,然后启动 GDB 图形化调试。
在 .vscode/launch.json 文件中填入以下内容:
{
"version": "0.2.0",
"configurations": [
{
"name": "GDB Debug Active File",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 GDB 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
// 关键!调试前先自动跑一遍上面的编译任务
"preLaunchTask": "GCC Build Active File"
}
]
}
配置好后,你就可以用鼠标在行号左边打断点,按 F5 启动调试,在左侧栏实时查看变量值了!
5. 使用 CMake 管理多文件项目
对于单文件,gcc 足够了。但如果是多文件项目,手写 gcc main.c utils.c helper.c ... 会很痛苦。这时就该用 CMake 。
项目结构示例:
project/
├── CMakeLists.txt
├── main.c
└── utils.c
CMakeLists.txt 模板:
# CMake 最低版本要求
cmake_minimum_required(VERSION 3.16)
# 项目名称和语言
project(my_c_project C)
# 设置 C 语言标准
set(CMAKE_C_STANDARD 11)
# 添加可执行文件,源文件列表写在后面
add_executable(app main.c utils.c)
构建流程:
# 创建一个 build 文件夹存放编译产物
mkdir build && cd build
# 生成 Makefile
cmake ..
# 执行编译
make
# 或者用 cmake 命令
# cmake --build .
6. 避坑指南与总结
-
编译参数的选择 (
-g和-Wall): 再次强调-g和-Wall的重要性。前者是 GDB 调试的入场券,后者能帮你提前发现无数低级错误(比如变量未初始化),省下大量调试时间。 -
VS Code 配置核对: 按下 F5 提示
preLaunchTask错误?检查launch.json里的preLaunchTask名字是否和tasks.json里的label完全一致。 -
适当使用 “Code Runner” 插件: VS Code 的 Code Runner 插件虽然方便,但它隐藏了具体的编译命令,一键运行很爽,但对学习毫无帮助。建议在学习阶段手动敲终端命令或使用我们配置的
F5调试流程,理解编译、链接的全过程。