开机 100 小时后的 0.34 秒:爱国者导弹为何没拦住那枚飞毛腿
目录
配图:AI 生成的概念示意图,非真实现场、产品界面或实验数据。
TL;DR:1991 年海湾战争期间,沙特达兰的一套爱国者防空系统没有拦截来袭的伊拉克飞毛腿导弹,导弹击中美军营房,造成 28 名美军死亡。美国审计署(GAO)的调查把原因归为软件时间计算的累积误差:系统连续运行约 100 小时后,时钟偏差约 0.34 秒,足以让雷达在错误的位置找目标。这不是说“一个小数就杀了人”:软件缺陷是直接原因,但补丁推广的时机同样是故事的一部分。
这是 1991 年 2 月 25 日发生的旧事,不是新闻。
一个除不尽的 1/10
爱国者系统的内部时钟以 0.1 秒为单位计数,计算时要把计数乘以 1/10 换成秒。问题在于 1/10 在二进制里是无限循环小数,系统只能用 24 位寄存器存储,末尾被截断。
每一次截断的误差极小,约为千万分之一秒的量级。但时钟一直在累加:开机时间越长,误差越大。连续运行约 100 小时后,累积的时间偏差约为 0.34 秒。
0.34 秒有多长
对人来说,这点时间连眨眼都不到。对飞毛腿来说却不一样:它的速度约每秒 1700 米,0.34 秒足以飞过五六百米。
爱国者拦截靠的是“距离窗口”:雷达发现目标后,系统根据时间推算目标下一刻出现的位置,只在那一小块空域里搜索。时钟偏了 0.34 秒,窗口就偏出了六百多米(常见引用数字为 687 米),飞毛腿根本不在窗口里,系统便判定“没有目标”,没有发射拦截弹。
警告和补丁
事后调查显示,这个缺陷并非无人知晓。资料显示,军方在袭击前已经得知长时间运行会导致时间漂移,临时的办法是定期重启系统;修复后的软件在袭击发生后的次日(2 月 26 日)才送到达兰。当天那套系统已连续运行了 100 多个小时,没有被重启。
为什么值得记住
这个案例常被放进软件工程课:一个看似无关紧要的舍入误差,在系统连续运行的条件下被不断放大,而设计时没人预想过它会连续开机这么久。它也提醒我们,“多久重启一次”这种运维规定,本身就可能是安全系统的一部分。