Merge pull request #92 from myrfy001/patch-4

增加使用VSCode进行可视化调试的指导
This commit is contained in:
chyyuu
2022-07-28 21:15:11 +08:00
committed by GitHub

View File

@@ -355,3 +355,115 @@ GDB 调试支持*
- `CentOS 平台 <https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-centos6.tar.gz>`_
解压后在 ``bin`` 目录下即可找到 ``riscv64-unknown-elf-gdb`` 以及另外一些常用工具 ``objcopy/objdump/readelf`` 等。
VSCode 可视化调试支持
------------------------------
本节将介绍如何在VSCode可视化环境中进行调试。所使用的的环境为Codespace + 本地VScode。网页版本的VSCode没有试过个人感觉使用本地VSCode连接到Codespace会比使用在线版本稳定一些。具体方法就是在打开Codespace时点击Open In Visual Studio Code即可
.. attention::
本操作指南参考了2022版实验手册以及kidcats同学在http://rcore-os.cn/rCore-Tutorial-Book-v3/chapter0/5setup-devel-env.html所发表的评论内容。
第一步我们需要安装RiscV对应的GDB调试器对应不同操作系统的调试器的下载地址可以参考上一节给出的链接。因为我们的Codespace是在Linux环境下的所以我们可以在Terminal中使用如下命令
.. code-block:: bash
cd /tmp
wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14.tar.gz
tar -zxf riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14.tar.gz
cd riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-linux-ubuntu14/bin
sudo cp ./* /usr/local/bin/
cd /usr/local/bin/
sudo chmod 777 ./*
上述shell命令进行了以下操作
1. 下载调试器到一个临时路径
#. 解压缩
#. 将调试器复制到/usr/local/bin目录下
#. 确保文件权限正确
完成上述操作后新打开一个Terminal窗口在任意目录下运行 ``riscv64-unknown-elf-gdb`` ,应该都可以找到这个可执行文件。
第二步安装并设置VSCode插件
首先打开VSCode的插件管理器搜索并安装插件 ``C/C++`` ,随后在 ``.vscode`` 目录下新建 ``launch.json`` 文件,并写入如下内容:
.. code-block:: json
{
// 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": [
{
"type": "cppdbg",
"request": "launch",
"name": "Attach to gdbserver",
"program": "${workspaceFolder}/os8/target/riscv64gc-unknown-none-elf/release/os",
"miDebuggerServerAddress": "localhost:1234",
"miDebuggerPath": "riscv64-unknown-elf-gdb",
"cwd": "${workspaceRoot}/os8",
}
]
}
注意要修改其中的 ``program````cwd`` 两项为自己当前要调试的代码的路径,上面的例子是在调试 ``os8`` 这个实验。
其中的 ``type`` 字段指定的 ``cppdbg`` 类型的调试器,是由我们刚才安装的 ``C/C++`` 插件提供的, ``miDebuggerServerAddress`` 指定了一个本地的1234端口开始调试后VSCode会控制debugger去连接本机的1234端口而我们后续启动qemu后qemu会在1234端口监听作为一个服务器等待调试器连接上来。
第三步,调整项目编译配置
打开对应实验目录下的 ``Cargo.toml`` 文件例如你在开发os8那么就是 ``os8/Cargo.toml`` 文件,在其结尾添加如下几行:
.. code-block:: json
[profile.release]
debug = true
opt-level = "s"
这段配置的意思是说我们要覆盖默认release模式编译的参数默认情况下release模式的编译会移除debug信息也就是 ``debug=false`` ,并且使用 ``opt-level=2`` ,也就是最高级别的优化进行编译,这样会导致打断点的时候很痛苦,很多代码都被优化的面目全非,对调试很不友好。
在上述代码中我们将debug信息保留并且使用 ``s`` 级别进行优化,这里可选的其他级别还有 0、1、2、z、s三种其中设置成2的话相当于没有设置因为release模式默认就是2如果设置成0的话经过我的实验会导致内核加载的时候直接崩溃掉我初步猜测是因为0表示关闭优化关闭后的内核二进制文件体积有点大以上是乱猜的时间有限没有去详细验证感兴趣的同学欢迎后续指正
如果设置为1的话感觉还是会有很多地方被优化导致代码很多地方无法打断点。经过个人实验感觉选择 ``s`` 级别可以在代码大小和优化之间取得一个比较好的平衡。
第四步修改Makefile文件
打开对应实验目录下的 ``Makefile`` 文件例如你在开发os8那么就是 ``os8/Makefile`` 文件,在其结尾添加如下几行:
.. code-block:: bash
dbg: build
qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -drive file=$(FS_IMG),if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 -s -S
聪明的同学们应该可以发现上面这一段代码是复制了Makefile中 ``debug`` 目标的配置并且把里面的启动tmux和gdb相关的部分给去掉了只保留了启动qemu的命令仅此而已。
之所以要说这个是因为os6开始qemu的启动命令增加了文件系统相关的内容 而os6之前的qemu启动命令是比较简短的这里是以os8为例进行说明的如果你要调试的是os1~os5的程序那么你现在就知道应该怎么修改上面的代码了。
上面启动命令的核心就是后面的 ``-s````-S`` 两个参数第一个小写s告诉qemu启动之后在1234端口监听等待调试器连接第二个大写S表示在调试器连接上来之前别运行程序等到调试器让你开始跑以后你再开始执行这样就给了我们挂接调试器的时间。
好了现在可以开始享受调试过程了。首先进入到代码目录里例如os8这个目录然后输入
.. code-block:: bash
make dbg BASE=2
之后是照常的编译流程编译完成后Terminal会卡在启动qemu后的状态此时在VSCode中按下F5键就可以享受调试啦~
再送上一个小提示如果你关心的某个变量在调试过程中被优化掉了你可以试着在这个地方加一个print语句打印一下这个变量的内容这样大概率可以防止编译器优化掉这个变量。
使用上述方法调试只要保证目录结构相对正确那么编译生成的elf文件中也保留了诸如easy-fs文件系统相关符号的信息也就意味着在调试os6的时候你可以在单步调试的过程中从kernel所在的crate直接跟踪执行跳转到easy-fs的源码中so cool!
最后,如果大家:
* 对Cargo.toml的配置文件感兴趣可以参考 <https://doc.rust-lang.org/cargo/reference/profiles.html>
* 对VSCode、GDB、qemu之间的互相调用关系感兴趣可以参考<https://www.bilibili.com/video/BV1jP4y1u7Nb>