Debug xv6 with CLion - yaodio/xv6-vi GitHub Wiki

在命令行中用 gdb debug xv6 的资料较多,这也是 MIT 6.828 的其中一节实验。本节中,着重介绍如何使用 Clion IDE 调试 xv6。

本地调试

如果你正好用一台装了 linux 的电脑并在其上开发 xv6,可以用这个方法。

准备好 xv6-vi 的源代码后,用 CLion 打开该文件夹。

点击左上角 Settings,向下找到 plugins,安装一个 Makefile support 插件:

Makefile-plugin

安装完成后,IDE 右上角会出现一个 "make",点开会发现两个 Makefile,展开第一个 Makefile,会发现所有主 Makefile 的 target。我们点击 qemu 然后回车,会发现在 IDE 底下 terminal 中开始跑 "make qemu" 的指令。

make-configuration

点击右上角绿色三角左边的 qemu,Edit Configurations,你会看到这个 Makefile configuration。如果你把 Targets 里面的 qemu 去掉,那么就是一个什么都不带的 "make";如果你在上面写 "clean",那么就是 "make clean"。

如果你希望在 "make qemu" 之前 "make",可以在 qemu 的 configuration 的 "Before launch" 下,点击加号添加一个 "make" 的 configuration。同理,如果你想在 "make" 之前 "make clean" 一下,就在 make 的 configuration 里加一个 clean 的 Before launch。

run-before

下面,我们添加一个 qemu-gdb 的 configuration 并运行。你会在 terminal 中看到如下信息:

qemu-gdb

留意最后的 tcp::26000,这个是 qemu 暴露出来的调试端口号。现在,让我们回到 Edit Configurations,左上角按加号,添加一个 GDB Remote Debug。名字随意,'target remote' args 填 localhost:26000,这个 26000 就是前面说的端口号,不同机器上可能不一样。Symbol file 填 path-to-xv6-vi/kernel,Sys-root 填path-to-xv6-vi/

debug-config

接下来就可以打断点了。首先运行 qemu-gdb,然后运行 gdb remote debug,你会看到 xv6 的小黑窗跑起来了,并且会在断点处停下来。现在,你可以和调试普通程序一样调试 xv6 了!

不幸的是,这种调试方法似乎不能调试用户程序,例如 ls, cat,当然 vi 也是不行的。因为它们是先编译成 elf 再被 mkfs 程序直接二进制写入 fs 的(见 Makefile fs.img)。但是至少你可以调试系统调用,如 console.c 中我们修改过的关于终端显示的一些 api。想要调试 xv6-vi 的话,恐怕只能在源代码中添加一些 printf

好消息是,你不必担心在源代码中添加过多打印语句会破坏程序的功能。我们提供了一个 logging 的宏定义(见 vulib.h):

#ifdef RUN_WITH_TRACE
#define logging(info, msg) printf info; printf msg
#else
#define logging(info, msg)
#endif

当没有定义过 RUN_WITH_TRACE 这个宏时,logging 被定义为空。我们在 Makefile 中定义了开关规则:

ifdef TRACE
CFLAGS += -D RUN_WITH_TRACE
endif
include vi/Makefile

当你运行 "make qemu TRACE=true" 时,我们会在编译 vi 的指令中添加 -D 选项,使得 RUN_WITH_TRACE 宏被定义。而当你只是简单地 "make qemu" 时,logging 将为空,相关的打印语句都不会被执行。

远程调试

如果你是使用 Clion 连接一台远程的服务器,可以参考:XV6 REMOTE DEBUG USING CLION。但是由于 xv6-vi 涉及到 cga 显示,必须要用 gui 才能运行,所以不能用 qemu-nox。因此,建议使用本地(或本地虚拟机)调试。