VSCode调试C语言程序

HarderHeng Lv5

一、环境介绍

  • Windows11 24H2
  • WSL2
  • Ubuntu 22.04

Linux系统下gdb工具默认安装好,使用VSCode进行WSL远程连接。

二、原理介绍

VSCode进行调试时,需要一个launch.json,这个配置文件描述了使用什么样的调试器,以及进行调试时的其他配置。

如果在VSCode中要进行调试工作,必须要在.vscode文件夹中有一个能完成调试任务的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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
"version": "0.2.0", // 使用的 launch.json 版本

"configurations": [ // 配置调试器的配置列表
{
"name": "Hpatchi Debug", // 调试器配置的名称,可以自定义,可以区别不同的调试器配置
"type": "cppdbg", // 调试器类型为 C++ 调试
"request": "launch", // 请求启动调试会话
"program": "${workspaceFolder}/hpatchi", // 可执行文件的路径,主要的修改点,这里就是我的工作目录下的hpatchi

// 程序启动时的参数,会将这些参数依次输入给启动调试的程序
"args": [
"-f",
"${workspaceFolder}/TestDemo/FBCM-0056.lbf",
"${workspaceFolder}/DiffFile",
"${workspaceFolder}/newFile-00D7.lbf"
],

"stopAtEntry": false, // 是否在程序入口处停止

"cwd": "${workspaceFolder}", // 工作目录
"environment": [], // 环境变量设置
"externalConsole": false, // 是否使用外部控制台

// 使用 gdb 调试器,也可以设置成别的调试器
"MIMode": "gdb",

// 配置 gdb的初始化命令
"setupCommands": [
//启用漂亮打印,输出格式对齐
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
//防止gdb调试进入标准库函数,实测没啥用,可以不加
{
"description": "防止 gdb 打开标准库函数",
"text": "-interpreter-exec console \"skip -rfu std::.*\"",
"ignoreFailures": false
}
],

"symbolLoadInfo": {
"loadAll": false,
"exceptionList": ""
},
// 在启动调试会话之前运行的任务,启动在task.json中提前配置好的任务名称。
//"preLaunchTask": "Build",

// gdb 调试器的路径,使用什么调试器就换成对应的路径,可以使用 which 命令找到一个程序的位置
"miDebuggerPath": "/usr/bin/gdb"
}
]
}

三、GDB原理

GDB是默认的c语言调试器,一般和gcc一起使用。

如果要使用gdb进行调试,使用gcc编译时就需要进行一些操作。

使用gcc编译需要在编译命令后加上-g,这样进行编译时gcc就会自动将源代码和编译后的机器语言对应,就可以进行调试追踪。

一定要在.c文件的编译阶段加上-g的命令才能正确生成调试信息,如果在链接阶段加上-g命令是指保留.o文件中的调试信息。即如果不在编译阶段生成调试信息,那这个文件在最后调试时就不会包含调试信息。

推荐在gcc时使用的命令

  • -g 必须加上否则无法进行代码的追踪。
  • -Wall,warn all的缩写,编译时会将所有的warn警告提示出来。
  • -O0 不进行编译优化,防止代码的顺序被调整或者某些调试变量被优化掉。

GCC的编译优化问题

gcc进行编译时会默认进行优化等级为O1的优化,编译器会尝试简单的优化代码流程和变量。

对应的如果进行了优化,部分调试信息就会减少,所以在调试过程中要慎重选择优化等级。

较低的优化等级可以提升编译速度,但是会导致较慢的执行速度或者较大的文件大小。使用比较高的优化等级时可以根据需要优化执行速度和文件大小,但是会牺牲编译的时间。

四、如何在Make项目中进行调试

上面介绍了如果要进行调试需要在执行gcc命令进行编译时加上**-g**的命令。

Make项目中往往很多文件都是通过隐含规则自动推导出来的,这时候我们就无法显式的加上-g命令来生成调试信息。只有在编译阶段生成了调试信息的文件,在最终调试时才能把代码运行过程和源文件对应起来。

遇到这种情况我们可以在CFLAGS变量中加入-g命令,CFLAGS中的所有参数都会被编译器默认使用,不管是自动推导还是使用gcc命令进行编译。

五、tips

我在调试文件的过程中,只在最后一步可执行文件后面加入了-g命令,导致的后果就是只有这个可执行文件的源文件可以被调试模式追踪,其他的源文件都没法进行调试。

在这里我尝试对makefile进行修改,然后使用了一些命令来查看make将会执行的命令。

make -n可以将make将会执行的命令,不管是显式规则规定的还是自动推导的,所有的命令都会显示出来,然后我将这些信息直接重定向输出到一个文件,接着修改一次makefile,再进行一次输出,我就得到了包含着make执行的命令的两个文件。

使用vimdiff命令就可以在vim中看到两个文件的区别之处,但是vim毕竟是一个命令行工具,如果需要更复杂的文本操作,还是需要使用VSCode,并且VSCode支持更多的插件和操作,自然使用起来就更方便。

  • Title: VSCode调试C语言程序
  • Author: HarderHeng
  • Created at : 2024-11-28 17:34:29
  • Updated at : 2024-11-29 11:32:19
  • Link: https://harderheng.life/2024/11/28/VSCode调试C语言程序/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments