yzhe819's Blog

MIT 6.S081 实验室指导

2022.06.07

本篇文章是原始Lab guidance的机器翻译

介绍作业难度的划分以及一些调试建议

原文链接为:Lab guidance

作业的难度

每个作业都表明它的难度:

  • 容易:不到一个小时。这些练习通常是后续练习的热身练习。
  • 中度:1-2 小时。
  • 硬:超过 2 小时。通常,这些练习不需要太多代码,但要正确编写代码却很棘手。

这些时间是我们预期的粗略估计。对于一些可选任务,我们没有解决方案,难度是一个疯狂的猜测。

练习一般不需要太多的代码行(几十到几百行),但代码在概念上很复杂,而且通常细节很重要。因此,在编写任何代码之前,请确保为实验室完成了指定的阅读,通读相关文件,查阅文档(RISC-V 手册等在参考页面上)。只有当你牢牢掌握了任务和解决方案后,才开始编码。当您开始编码时,分小步实施您的解决方案(作业通常会建议如何以较小的步骤分解问题)并测试每个步骤是否有效,然后再进行下一个步骤。

警告:不要在实验室到期的前一天晚上开始实验室;在多天的多个会话中进行实验室的时间效率更高。操作系统内核中的错误表现可能令人困惑,可能需要经过深思熟虑和仔细调试才能理解和修复。

调试提示

以下是调试解决方案的一些提示:

  • 确保您了解 C 和指针。Kernighan 和 Ritchie 所著的《C 编程语言(第二版)》一书对 C 进行了简洁的描述。 这里提供了一些有用的指针练习。除非您已经完全精通 C,否则不要跳过或略读上面的指针练习。如果你没有真正理解 C 语言中的指针,你将在实验室中遭受数不清的痛苦和苦难,然后最终以艰难的方式理解它们。相信我们; 你不想知道什么是“困难的方式”。

    一些指针常用习语特别值得记住:

    • 如果int *p = (int*)100, 那么 (int)p + 1(int)(p + 1) 是不同的数字:第一个是101但第二个是104。将整数添加到指针时,如第二种情况,整数隐式乘以指针指向的对象的大小。
    • p[i]被定义为与 相同*(p+i),指的是 p 所指向的内存中的第 i 个对象。当对象大于一个字节时,上述添加规则有助于此定义工作。
    • &p[i]与 相同(p+i),产生 p 指向的内存中第 i 个对象的地址。

    尽管大多数 C 程序从不需要在指针和整数之间进行转换,但操作系统经常这样做。每当您看到涉及内存地址的加法时,请询问自己是整数加法还是指针加法,并确保所添加的值被适当地相乘。

  • 如果您的练习部分有效,请通过提交代码来检查您的进度。如果你稍后破坏了某些东西,你可以回滚到你的检查点并以更小的步骤前进。要了解有关 Git 的更多信息,请查看 Git 用户手册,或者,您可能会发现这个 面向 CS 的 Git 概述很有用。

  • 如果您未通过测试,请确保您了解您的代码未通过测试的原因。插入打印语句,直到您了解发生了什么。

  • 您可能会发现您的打印语句可能会产生很多您想搜索的输出;一种方法是 在脚本内运行make qemu(在您的机器上运行),它将所有控制台输出记录到一个文件中,然后您可以搜索该文件。不要忘记退出脚本man script

  • 在许多情况下,打印语句就足够了,但有时能够单步执行某些汇编代码或检查堆栈上的变量会很有帮助。要将 gdb 与 xv6 一起使用,请在一个窗口中运行 make make qemu-gdb,在另一个窗口中运行gdb(或riscv64-linux-gnu-gdb),设置断点,然后按 ‘c’(继续),xv6 将一直运行,直到遇到断点。(有关有用的 GDB 提示, 请参阅使用 GNU 调试器。)

  • 如果您想查看编译器为内核生成的程序集是什么,或者要找出特定内核地址处的指令是什么,请查看文件kernel.asm,该文件是 Makefile 在编译内核时生成的。(Makefile 还为所有用户程序 生成.asm 。)

  • 如果内核崩溃,它将打印一条错误消息,列出程序计数器崩溃时的值;您可以搜索kernel.asm以找出程序计数器崩溃时在哪个函数中,或者您可以运行(运行 以获取详细信息)。如果要获取回溯,请使用 gdb 重新启动:在一个窗口中运行 ‘make qemu-gdb’,在另一个窗口中运行 gdb(或 riscv64-linux-gnu-gdb),在 panic (‘b panic’) 中设置断点,然后后跟“c”(继续)。当内核到达断点时,键入“bt”以获取回溯。 addr2line -e kernel/kernel pc-valueman addr2line

  • 如果您的内核挂起(例如,由于死锁)或无法继续执行(例如,由于执行内核指令时出现页面错误),您可以使用 gdb 找出它挂起的位置。在一个窗口中运行“make qemu-gdb”,在另一个窗口中运行 gdb (riscv64-linux-gnu-gdb),然后是“c”(继续)。当内核出现挂起时,在 qemu-gdb 窗口中按 Ctrl-C 并键入“bt”以获取回溯。

  • qemu有一个“监视器”,可以让您查询模拟机器的状态。您可以通过键入 control-a c 来获得它(“c”用于控制台)。一个特别有用的监控命令是info mem来打印页表。您可能需要使用cpu命令来选择要查看的核心信息 mem,或者您可以使用make CPUS=1 qemu启动 qemu以导致只有一个核心。

学习上述工具非常值得。