你们是否遇到过以下令人抓狂的情况?

bash: curl: command not found

fatal error: 'sys/cdefs.h': No such file or directory
#include <sys/cdefs.h>

make[2]: *** run: No such file or directory.  Stop.
Makefile:31: recipe for target 'run' failed
make[1]: *** [run] Error 2
...

计算机世界:一切皆可调试

程序 = 计算机系统 = 状态机

  • 机器永远是对的
  • UNIX 世界里你做任何事情都是在编程
    • 因此配置错、make 错等,都是程序输入/配置有 bug
    • (输入/配置可以看成是程序的一部分)

所有问题都可以用调试理论解决

  • 你写了一个程序,现在这个程序出 bug 了 (例如 Segmentation Fault),你是怎样排查这个问题的?
    • curl: command not found
    • 'sys/cdefs.h': No such file or directory
    • make: run: No such file or directory

使用调试理论

Debug (fault localization) 的基本理论回顾:

  • Fault (程序/输入/配置错) → Error → Failure (可观测)
    • 绝大部分工具的 Failure 都有 “原因报告”
      • 因此能帮助你快速定位 fault
    • man perror:标准库有打印 error message 的函数

如果问题不能帮你定位到 fault/error?

  • 出错原因报告不准确或不够详细
  • 程序执行的过程不够详细
    • 既然我们有需求,那别人肯定也会有这个需求
      • 一定有信息能帮助我们!

使用调试理论 (cont'd)

正确的方法:理解程序 (状态机) 的执行过程

  • ssh:使用 -v 选项检查日志
  • gcc:使用 -v 选项打印各种过程
  • make:使用 -n 选项查看完整命令
    • make -nB | grep -ve '^\(echo\|mkdir\)' 可以查看完整编译 nemu 的编译过程

各个工具普遍提供调试功能,帮助用户/开发者了解程序的行为

例子:找不到 sys/cdefs.h

'sys/cdefs.h': No such file or directory,找不到文件 (这看起来是用 perror() 打印出来的哦!)

  • #include = 复制粘贴,自然会经过路径解析
  • (折腾20分钟) 明明 /usr/include/x86_64-linux-gnu/sys/cdefs.h 是存在的 (man 1 locate) → 极度挫败,体验极差

推理:#include <> 一定有一些搜索路径

  • 为什么两个编译选项,一个通过,一个不通过?
    • gcc -m32 -v v.s. gcc -v

这是标准的解决问题办法:自己动手排查

  • 在面对复杂/小众问题时比 STFW/ChatGPT 有效

更多的案例 1:视频播放翻车

视频播放翻车了,但我没翻车!

  • 程序员的本能:机器永远是对的

更多的案例 2: NOI Linux on USB

ubuntu-noi.iso

  • 不可引导
  • 包含了残缺的 UEFI Boot Loader
  • ISO9660 (只读) 镜像
  • 😂😂😂😂😂

重做一个引导盘

  • 能正确引导、看到安装 (splash) 界面
  • Unable to find a medium containing a live file system
    • 网上给出的各种方案 (包括拔了再插) 都无果
    • RTFSC