1996 年 6 月 4 日,欧洲航天局(ESA)首次发射了阿丽亚娜(Ariane)5 ,这在太空探索史上是一个重要时刻。
然而,这次任务却因一行代码导致火箭发射后发生了爆炸,价值近 5 亿欧元。
在起飞后约 30 秒,火箭在大约 3700 米的高度上偏离了预定飞行路径并发生解体和爆炸。
这次失败的主要原因在于制导系统中的一个软件缺陷,该系统负责调节火箭的航向。
归根结底是由于一个编码错误,这段代码原本属于十年前阿丽亚娜4 型火箭的一部分,但在阿丽亚娜5 型火箭的设计中没有被适当更新或移除。
在火箭升空后,制导系统负责持续监测并跟踪火箭的飞行轨迹,并将这些数据传输给主计算机,在这一过程中,制导系统需要将测得的速度数据从 64 位浮点数格式转换为 16 位有符号整数格式。
然而,浮点数和整数在表示数值范围上存在本质差异:
16 位
-
无符号整数(Unsigned Integer)范围:0 到 65535
-
有符号整数(Signed Integer)范围:-32768 到 32767
64 位
-
无符号整数(Unsigned Integer)范围:0 到 18446744073709551615
-
有符号整数(Signed Integer)范围:-9223372036854775808 到 9223372036854775807
16 位无符号整数能够表示的数值范围是 0 到 65535,而16位有符号整数(使用一个位来表示正负号)能够表示的数值范围是 -32768 到 +32767。
如果 64 位浮点数表示的速度值超出了 16 位有符号整数的表示范围,那么在转换过程中就会发生溢出。
火箭发射后,由于速度数据超出了 16 位整数的最大表示能力,转换失败,导致制导系统无法正确传递速度信息给主计算机,从而发生了爆炸。
正常情况下,一个稳健的系统设计会包含错误处理机制,以应对此类溢出情况,但阿丽亚娜5 号火箭的系统设计中并未包含这种机制。结果,由于这个 Bug 火箭失去了导航和姿态控制,最终导致了火箭爆炸。
这次事件告诫我们在软件开发中要避免直接复制粘贴代码,确保异常处理和充分测试,并进行代码审查和建立备份系统,以增强软件的可靠性。
启示:
-
代码复用的风险:即使是从旧系统中复制的代码,也需要经过彻底的审查和测试,以确保它适用于新系统。
-
异常处理:系统设计中应包含异常处理机制,以便在出现错误或异常数据时能够妥善响应,避免灾难性后果。
-
数据类型转换:在进行数据类型转换时,需要确保转换的安全性和准确性,避免因数据溢出或精度丢失导致的问题。
-
系统测试:全面的系统测试是必要的,包括单元测试、集成测试和压力测试,以确保系统在各种条件下都能正常工作。
-
代码审查:定期进行代码审查,以识别和修正潜在的缺陷和错误。
-
文档和注释:保持良好的文档记录和代码注释,有助于理解代码的用途和限制,减少误解和错误使用。
-
备份和冗余:设计备份系统和冗余机制,以提高系统的可靠性和容错能力。
-
持续学习和改进:从失败中学习,不断改进设计和开发流程,以防止类似事件再次发生。
-
跨团队沟通:加强不同团队之间的沟通,确保所有相关人员都了解系统的所有方面,包括潜在的风险和限制。