Yanyan's Wiki 操作系统 (2023)

2022 《操作系统》实验须知

TL; DR

从 Github 下载指定的 repo 完成实验。

  • 我们将使用我们的脚本/Makefile、在我们的环境下进行评测。因此如果你在本地修改了编译选项 (如去掉了 -Wall -Werror 等)、硬编码了路径 (fopen("/home/jyy/log.txt", "w")) 等,提交后可能会发生编译/运行错误。
  • 因算力有限,Online Judge 仅对本校同学开放**。
  • 请大家自觉不要把自己的实验作业代码公开。如果你本着 “炫耀” 的态度公布,那你的代码很可能写得很烂不值得炫耀。请停止这种对学弟和学妹造成伤害的行为。

1. 获取实验框架代码

关于本课程的实验环境,请参考第一周的阅读材料。本课程所有实验都托管在同一个仓库中。在命令行中执行

$ git clone https://github.com/NJU-ProjectN/os-workbench-2022

获得框架代码,将会克隆 os-workbench-2022 到当前目录。首次 clone 后你会得到一个近乎为空的 Git repo:

.
├── .git/
├── .gitignore
├── Makefile
└── Makefile.lab

每个实验的指南中都有获取该实验框架代码的说明。请妥善保管 os-workbench-2022 目录。如果在多个地点完成作业,请将整个目录完整移动以保持 Git 记录的完整。如遇问题请联系老师或助教。

2. 提交实验作业

我们已经为选修课程的同学生成了唯一的秘钥,并以邮件形式发送到你的学号@smail.nju.edu.cn 邮箱,有遗漏的请联系 jyy。此外,我们接受本校非选课同学 (本研皆可) 的 TOKEN 申请 (请用你的 @smail.nju.edu.cn 邮箱申请,注明姓名和学号)。

配置好 Makefile 中的 TOKEN 环境变量后,在相应的实验目录中 (而不是项目根目录) 中执行以下命令完成提交:

$ make submit

如果提交成功,命令行中会看到:

$ make submit
[SUCC ✓] Received OS2022-M1 学号 (姓名) upload.tar.bz2 at 20:17:26

提交成功后,将你收到的秘钥粘贴到网页的右上角,在实验网页上查看提交结果。注意我们只收取 os-workbench/.git 和目录中的 pdf 文件 (实验报告)。因此,如果你只是修改了代码而没有执行过 make 或手工的 git commit,这些改动将不会被反映到 Online Judge。

3. 使用 Git 管理源代码

在得到 Git repo 以后,默认处于 main 分支。你可以本学期全部在 main 分支上工作,但也可以自由创建自己的分支。make submit 会自动提交 “当前” (HEAD) 的 commit。

此外,我们会在 make 时自动将代码提交到当前分支 (为什么?)。如果你对 Makefile 有修改,请保留 Git 追踪部分,Git 记录将会作为我们筛选、检查提交的参考。如果你因为意外丢失了 Git 记录,只要你遵守学术诚信,就不必担心,Git 记录不参与评分。

如果你希望手工管理自己的代码,可以使用 git 的 tag 机制,创建 tag 同样可以使你能追溯到历史的版本。

4. 实验与评分

4.1 Mini Labs

  1. 编写可移植的代码。我们会在 32/64-bit 两个平台上测试你的代码,因此请不要对指针类型的大小等作出假设。
  2. 全程只有一个 C 源代码文件,请尽量控制在 500 行以内。参考实现一般在 100-200 行,测试通过即得满分。Mini Programming Labs 的扩展性极高,你可能写出规模很大的项目。请克制你的欲望。
  3. 只允许使用指定的 Makefile 编译 (使用 make)、只允许编辑已有的一个 .c文件。评测时,我们仅复制这一个 C 文件 (添加其他文件在 Online Judge 会导致编译错误)。
  4. 不需要实验报告

4.2 OS Labs

  1. 同样需要编写可移植的代码。我们将在 native, x86_64-qemu, x86-qemu 三个平台上测试。
  2. 需要撰写实验报告 (以 pdf 格式存储在实验目录中,参考各个实验的要求)。除非特殊情况,实验报告不建议超过 2 页 A4 纸。请在实验报告中描述你在实验中遇到的特别值得一提的事件,例如你代码的架构设计、特别精巧的实现、遇到印象深刻的 bug 等。无需事无巨细交代清楚;好的代码不言自明。

4.3 评分规则

测试用例分为两个等级 (easy 和 hard),easy 通常是一些 “冒烟测试” (smoke test),即使用最典型简单的方式运行程序,检查程序是否 crash 以及输出合理的结果。Hard 则是更接近实际应用场景的测试用例。虽然你不能看到程序的日志输出 (否则测试用例很容易泄露),但我们会对每个测试用例提供一定的解释,以帮助大家诊断问题。与此同时,我们也会保留一定数量的测试用例用于评分使用,最终的评分将结合自动评测、保留测试用例和人工评价给出。评分规则:

⚠️ 评分规则

在没有抄袭作弊 (如硬编码答案、故意骗过 Online Judge 而不实现实验要求等) 的前提下

Mini Labs (完全客观评分)

  • Rejected, 编译错误或没有通过任何测试用例: 10% (诚信分)
  • Accepted, 部分 easy 测试通过 (此时不运行 hard 用例): 50%
  • Accepted, 全部 easy 测试通过、部分 hard 测试通过: 75%
  • Accepted, 通过全部 easy/hard 测试: 100%

OS Labs (几乎完全客观评分)

  • Rejected, 编译错误或没有通过任何测试用例: 10% (诚信分)
  • Accepted, 部分 easy 测试通过 (此时不运行 hard 用例): 30%
  • Accepted, 全部 easy 测试通过、部分 hard 测试通过: ≥ 50%,剩余部分由隐藏的测试用例/人工评价给出
  • Accepted, 通过全部 easy/hard 测试: ≥ 75%,剩余部分由隐藏的测试用例/人工评价给出
  • 没有通过全部 easy 测试用例的作业将没有人工评分的机会 (即意味着实验报告不得分。但我们会阅读你的反馈)。

我们希望这个机制能够强制大家写出高质量的代码。一开始会很痛苦,但之后你方能体会其中的良苦用心。

⚠️ 按时提交奖励

每个实验都设有 Soft deadline。Soft deadline 之前提交:成绩 + 5% (如按时提交空项目将得到 15% 诚信分)

  • 单项得分可以超过 100% (例如按时提交正确的 Mini Lab 将得到该 lab 的 105%)
  • Mini/OS Labs 得分由所有单个 Mini/OS Lab 得分总和而成,不超过 Mini/OS Labs 总分的 100%
  • 如果发现问题希望修复 (一旦进行过尝试),之后的提交将不享受加分;但之前已经获得带按时提交加分的分数不会被消除 (以分数高的计算)

所有实验在 Hard deadline (通常是期末考试后的一小段时间) 截止。请《计算机系统基础》课上将实验拖延到最后的同学吸取教训。

4.3. Online Judge 环境

Mini/OS Lab 都在 Online Judge 评测。程序在容器中编译、运行,并由机器自动判定结果是否正确。在此基础上,最终实验的评分仍有一部分由助教决定。你的程序将在以下环境运行:

  • Ubuntu 20.04 容器 (Docker)。容器中仅有最小的必要系统工具。使用以下 Dockerfile 配置与在线评测一致的环境;我们开放了容器的 SYS_PTRACE 权限;

    FROM ubuntu:20.04
    ENV DEBIAN_FRONTEND=noninteractive
    RUN apt-get update
    RUN apt-get install -y build-essential gcc-multilib qemu-system strace gdb sudo python3 libsdl2-dev libreadline-dev llvm-11 gcc-riscv64-linux-gnu
    RUN useradd -ms /bin/bash user
    USER user
    WORKDIR /home/user
    
  • Mini Labs 直接在容器中执行 (non-root user);OS Labs 在容器中的 QEMU 虚拟机 (tcg 模式) 运行;

  • 容器总内存限制 512 MiB,超过内存限会导致进程被杀死。超过一定时限未执行完的容器也将被杀死。

Online Judge 的最大特点就是严格。有任何差错 (因为环境/配置等引发的编译错、细小的输出错误) 都将被 Online Judge 捕捉到。这有助于帮助大家摆脱 “糊弄” 的习惯,编写正确的程序。

系统课程的 labs 和 OJ 题有一点不同:大部分问题没有 “绝对正确” 的标准输出。因此我们并不是简单地运行程序、比对结果,而是有一定系统化地测试你的程序:

  • 在多个环境下运行你的程序,如 i386 (32 位) 和 x86-64 (64位),因此不可移植的代码可能无法编译;
  • 在模拟出的环境中执行程序,例如在线程调度时插入一些随机的 delays,从而提高某些并发 bug 触发的概率;
  • 链接我们修改过的库函数,例如 (在某些 lab 中) 使 malloc() 随机返回 NULL
  • 解析程序的 log,并观察其中是否有 bug 出现的迹象。例如程序 crash 将被判定为不正确、缺少某个重要输出也将被判定为不正确。

⚠️ 温 (血) 馨 (的) 提 (教) 示 (训)

Online Judge 平台并行度有限,遇到评测任务较多时请耐心等待,请避免在截止日期前极限操作,否则你将来不及修复 Online Judge 返回的错误。

4. Makefile 导读

初始时,你 clone 下的目录中只有 Makefile, Makefile.lab.gitignore 三个文件。在相应的实验页面上,有获取实验代码的方法。以 Mini Lab 为例,如果一切顺利,在 minilab 对应的目录中 make,将会得到 xxxx-32 和 xxxx-64 两个文件,分别是 32 位和 64 位平台上的二进制代码 (或运行库)。

具体编译目标构成了以下流程图:

RTFSC,你可以把代码和这个流程对应上。同时,但你在编译的过程中可能会遇到一些错误。给大家的提示:

  1. (非常非常非常重要,新手经常忽略) 仔细阅读理解输出日志,尤其是错误信息。必要的时候使用一些命令行选项打印更多的日志
  2. 在 Google/Bing/Stackoverflow 用英文关键字搜索相应的错误,并尝试解决
  3. 禁止使用中文关键字,禁止使用百度/CSDN blogs。其中的很多不准确的信息可能会误导新手
  4. 再看一眼第一周的阅读材料

例如,在 64 位环境下,如果没有安装编译器和相应的运行库,则第一次编译就会失败;如果安装了,-m32 也会编译错误,例如:

In file included from ./pstree.c:1:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
   27 | #include <bits/libc-header-start.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [../Makefile:22: b-32] Error 1

这时候,两个反复提到的词再次出现:

  • RTFM: Read The Friendly Manual
  • STFW: Search The Friendly Web

其中的 “F” 让它们更具有传奇色彩。通过查阅官方文档和搜索互联网解决你遇到的问题,在《计算机系统基础》这门课中已经得到了充分的训练。再次强调要看清楚网上的解决方案是否适合你的系统环境,以及是否说明了出问题的原因。make 编译成功后,将会得到 pstree-32pstree-64 两个文件,在命令行中执行可以打印所有命令行参数。

⚠️ 编写可移植的代码

同一份代码,Makefile 会同时使用 -m32-m64 两个选项来编译。这 (强) (制) 大家写出可移植的代码。CERT C 编码规范是非常棒的阅读材料,也作为书籍出版,大家可以收藏一本电子版。

Creative Commons License    苏 ICP 备 2020049101 号