In [1]:
from mosaic import *
OS2023(8)
8. 调试理论与实践¶
Changelog & 反馈
- pstree 的 Hard Test Case: 需要包含 “pstree” 字样,以及输出到正确的流
- Online Judge 虽然增强了,但检查还是很松的 (仅检查进程)
背景回顾:在快节奏的《操作系统》课中,插入一些 (重要得要命但与操作系统不完全相关的) 休闲内容。
本讲内容:调试理论:Fault, Error 和 Failure;GDB 使用技巧。
In [2]:
slideshow('8.1')
调试理论给了大家在遇到 “任何问题” 时候 self-check 的列表:
- 是怎样的程序 (状态机) 在运行?
- 我们遇到了怎样的 failure?
- 我们能从状态机的运行中从易到难得到什么信息?
- 如何二分检查这些信息和 error 之间的关联?
看完之后的例子,你相信对这个过程会有更好的理解。
In [3]:
slideshow('8.2')
没错,我们只要能 “检查状态机的状态”,就可以调试/诊断计算机系统中遇到的 “任何问题”,有些看似莫名其妙的问题,在 trace/log 的帮助下,也就自然有了头绪。
In [4]:
slideshow('8.3')
In [5]:
demo('printf', 'd/printf.c')
In [6]:
demo('nondet', 'd/nondet.c')
In [7]:
demo('mutex', 'd/mutex', libs=['thread.h', 'thread-sync.h'])
In [8]:
slideshow('8.4')
In [9]:
demo('mem-error', 'd/mem-error.c')
Sanitizer 是一类重要的 “动态程序分析”。所谓动态,就是指观察程序的运行 (即状态机的执行)。动态分析能给出许多程序有趣的性质,包括性能和功能性的 bugs。相应地,也有静态程序分析,即不在实际的环境中运行程序,就能对程序的行为作出预测——编译器和编译优化就是一类重要的静态分析。
Take-away Messages¶
调试理论:bug 是如何发生的?
- Fault → (测试) → Error → (断言) → Failure
- 调试一切问题的 checklist
- 是怎样的程序 (状态机) 在运行?
- 我们遇到了怎样的 failure?
- 我们能从状态机的运行中从易到难得到什么信息?
- 如何二分检查这些信息和 error 之间的关联?
残酷的现实和难听的本质
- 道理都懂,但出 bug 了,还是不知道怎么办?一句难听的话:你对代码的关键部分还不熟悉。根据调试理论,你还不知道如何判定程序状态是否正确,或是对如何简化程序状态还没有经验:
- 编程基础不牢固
- 对项目代码不理解
- 最根本的原因:抱有 “我不理解这个也行” 的侥幸心理
课后习题/编程作业¶
1. 编程实践¶
针对你近期调试过的程序,通过配置 GDB、vscode 等,优化你的调试体验。我们建议把这些配置跟随实验框架,这会大幅提升你的实验体验,从而消除你 “我不理解这个也行” 的心态。