前言:

学习任何一件事情之前不要轻言放弃,看不懂是正常的,除非你是天才。任何事物的本身,除非你是机器,否则看不懂是很正常的,因为你第一次见到ta,就想全部了解ta的一切是很困难的。古人云 书读百遍其义自见。希望遇到困难能够认真的分析,而不是去抱怨。

首先 暑假7,8月的补档:看了22 24 jyy老师 的os 课程,给我感触最深的是,究竟大学学到怎么样才算完成期望了?是期末考试之前复习一个月,能拿一个好成绩,这样就算功德圆满了吗。把工科课学成文科课,当某些同学拿着95+的成绩而沾沾自喜时,我却深刻地意识到:这样子是不行的。当看到jyy老师现场debug 代码的时候,我知道我们落后太多,我们课堂上就像是 一个一个知识概念背诵,反复琢磨做题方式,但是无奈,应试教育就是这样。谁分高就用水, 这些都是闲话了

进入正题

看到 mit的大牛老师在mac的控制台进行gdb 调试,jyy老师用vscode 在调试代码,俗话说:工欲善其事,必先利其器。一个好的工具能大大节省我们的时间。那么如何配置好vscode 的调试工具呢。

我用的是阿里云ecs服务器,首先在vscode 下载相对应的ssh插件。 然后进入配置。

image-20240903212030315

launch.json

image-20240903212058322

主要在.vscode文件夹下面 生成launch.json文件。这是我们主要的配置文件。

然后配置一大堆参数。初看这些参数看不懂没关系,毕竟我们有ai,可以辅助我们阅读

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
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/kernel/kernel",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"miDebuggerServerAddress": "localhost:25000",
"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
}
]
}
]
}

不要担心,理解调试配置和设置可能需要时间,但只要按步骤操作,你一定能够掌握。让我帮你一步步简化和解释这些配置:

理解 launch.json

launch.json 文件是 VSCode 调试配置的核心文件。它告诉 VSCode 如何启动调试会话。对于你当前的设置,配置了如何连接到 GDB 服务器以进行调试。这里是简化版的解释:

  • version: 版本号,通常保持默认即可。
  • name: 调试配置的名称,可以任意命名,方便选择。
  • type: 指定调试类型,这里是 cppdbg 表示 C/C++ 调试。
  • request: 设置为 launch 表示启动调试会话。
  • program: 你要调试的程序的路径,这里是 ${workspaceFolder}/kernel/kernel,表示当前工作区下的 kernel 文件。
  • miDebuggerPath: GDB 调试器的路径,使用 gdb-multiarch 支持多种架构(包括 RISC-V)。
  • miDebuggerServerAddress: GDB 服务器的地址和端口,与你在 QEMU 启动时设置的端口一致。
  • setupCommands: 启动调试时执行的命令,-enable-pretty-printing 用于格式化显示复杂数据,-gdb-set disassembly-flavor intel 设置反汇编风格为 Intel。

这是我问gpt 给的答案。

当编辑好之后 在终端输入命令 make qemu-gdb

进行调试

image-20240903212436670

然后我们按f5开始调试 可能遇到下面的错误

image-20240903212523882

连接不上 ,这时候我们要找到这个文件

image-20240903212543058

把第三行注释掉

image-20240903212552591

然后再按f5 发现就可以调试了。

image-20240903212648946

调试四个选项:

  1. F5 - 继续 (Continue)
    功能: 继续执行程序直到遇到下一个断点或程序结束。
    用途: 当程序在某个断点处暂停时,使用 F5 可以让程序继续运行到下一个断点或程序结束。这是用来快速跳过调试时不需要关注的代码部分。
  2. F10 - 逐过程 (Step Over)
    功能: 执行当前行代码,并跳过函数调用。即使当前行代码调用了其他函数,调试器也不会进入这些函数的内部。
    用途: 当你想逐步执行程序而不进入函数内部时使用。适用于检查代码逻辑时,只关注当前函数的行为,而不需要详细跟踪被调用的函数。
  3. F11 - 单步调试 (Step Into)
    功能: 执行当前行代码,如果该行代码调用了其他函数,调试器将进入这些函数的内部,并逐步调试函数内部的代码。
    用途: 当你需要详细检查函数内部的执行过程时使用。适用于调试时需要深入到函数内部,了解函数如何处理输入或产生输出的场景。
  4. Shift + F11 - 单步跳出 (Step Out)
    功能: 执行当前函数的剩余部分,并返回到调用该函数的位置。即使函数内部有复杂的逻辑,调试器会运行完当前函数并停在返回位置。
    用途: 当你已经深入到函数内部并完成调试时,使用单步跳出可以快速返回到调用函数的位置,继续调试程序的其他部分。
    总结
    F5 (Continue): 继续运行程序直到下一个断点或程序结束。
    F10 (Step Over): 执行当前行代码,跳过函数内部。
    F11 (Step Into): 进入当前行代码调用的函数内部,逐步调试。
    Shift + F11 (Step Out): 跳出当前函数,返回到调用函数的位置。

总结:到这里就全部配置完了,我从中得到最大的体验就是,遇到事情不要慌,学会发现问题的本质,任何事情都是一步一步堆积起来的。