十年 kill bug 考古:为什么一条命令能杀掉整台机器
来源:alangrow.com — 2026-10
📋 概述
2026 年 9 月 24 日早晨,Endcrawl 出现一次短暂全站故障:作者刚敲下 sudo kill -TERM -1490947,想按进程组取消一次内测渲染,结果除 init 外所有进程都被杀掉。根因是 procps 4.0.4 里 kill(1) 的 getopt 分支——未识别选项时它只把短横线后的第一个字符放进 optopt,于是 -1490947 算出了 pid = -1,而给 -1 发信号等于向所有有权限的进程广播。作者顺着历史查下去,发现这不是孤例,而是十年里四个不同 bug 的轮回。
🔑 核心要点
- getopt 只把短横线后的第一个字符放进
optopt,-1490947 被算成 -1;在 root 下这等于杀掉除 init 外的一切。
- 十个字符的负 pid 看起来像选项:Linux 把 BSD 的位置解析改成 getopt 之后,负 pid 就一直在踩坑。
- 十年间四个 bug 分别出现在 Ubuntu 14(单字符负 pid 无效)、16(误杀全部)、18(段错误)、22(误杀当前 shell)。
- 每一版修复都只补一个用例、换来另一个回归,24.04 又退回到 16 那份已知有问题的代码。
- 作者结论:kill 这类「选项、信号名、信号编号、负 pgid 混在一起」的命令行,应当按位置解析 argv;FreeBSD 至今如此,从无解析 bug。
💡 金句
一个没被理解的故障,是迟早会再发生一次的故障。
👍 0
👎 0
← 返回 Lobsters 首页