Fork me on GitHub

Bug杀人

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

 

前记:偶然读到园子中的“让我头顶发凉的软件质量小故事”,对其中的软件缺陷引发的辐射事故很好奇,可惜作者一只游泳的鱼对事故的描述不很详细。好奇心驱动,做了一些深入的调查。中文报道方面只找到一篇极为简略的人民网简讯。但随后读到的国际原子能机构的详细报告,颇为震撼。

 

病人辐射致死,凶手竟是软件。2000年8月到2001年3月之间,在巴拿马(Panama)的国家癌症中心(IONInstituto Oncologico Nacional),由于软件错误计算了放射治疗中的辐射量,28位病人接受了过量的伽玛辐射。其中的17位病人数周的辐射后遗症折磨后,最终死亡。剩下的11人都受到严重辐射伤害。相关的医务人员被控谋杀,而生产放疗系统以及相关软件的美国公司(Multidata Systems International Corporation)被起诉。该事件曾引起计算机界的广泛关注,在Wikipedia的软件bug(Software Bug)词条中,这个事故作为第一个例证,用于说明Software Bug可能造成的危害。

 

这个事故是什么严重程度呢?下表是历史上的辐射事故列表 (未计入日本海啸辐射泄漏)

日期地点事件类型死亡人数受伤人数
06 Aug 1945 Hiroshima, Japan 广岛,日本 原子弹 45,000 (130,000) 60,000? (86,000)
09 Aug 1945 Nagasaki, Japan 长崎,日本 原子弹 20,000 (65,000) 50,000? (75,000)
04 Jul 1961 K-19 submarine, North Atlantic 北大西洋 海军反应堆事故 8 31
21 Mar 1962 - Aug 1962 Mexico City, Mexico 墨西哥 放射源丢失 4 1
24 May 1968 K-27 submarine, Barents Sea 巴洛支海 海军反应堆事故 9 83
1974 - 1976 Columbus, Ohio, USA 美国 辐射治疗事故 10 88
1980 Houston, Texas, USA 美国 辐射治疗事故 7 ?
05 Oct 1982 Baku, Azerbaidjan, USSR 苏联 放射源丢失 5 13
19 Mar 1984 Casablanca, Morocco 摩洛哥 放射源丢失 8 3
10 Aug 1985 K-431 submarine, Chazhma Bay, Vladivostok, Russia, USSR 苏联 反应堆事故 0 (10) 49
26 Apr 1986 - 06 May 1986 Chernobyl, Ukraine, USSR 切尔诺贝利,苏联 反应堆事故 28 (31) 238+
12 Sep 1987 - 29 Sep 1987 Goiania, Goias, Brazil 巴西 放射源丢失 5 20
10 Dec 1990 - 20 Dec 1990 Zarragosa, Spain 西班牙 辐射治疗事故 18 9
22 Aug 1996 - 27 Sep 1996 San Jose, Costa Rica 哥斯达利加 辐射治疗事故 7 81
Aug 2000 - 24 Mar 2001 Panama City, Panama 巴拿马 辐射治疗事故
17 11

修改自:Johnston's Archive

各国对辐射物管制极为严格,历史上的辐射事件也有限。巴拿马辐射事件发生于2000年,当时的放疗控制软件(TPS, treatment planning system)早已面世多年,却依然发生如此惨剧。

 

高能辐射,比如伽玛射线,可以杀死人体细胞(无论是健康的还是癌变的细胞)。放疗就是利用高能辐射线照射并杀死癌细胞,高的辐射量(radiation dose)可以更彻底的杀死癌细胞,防止癌细胞的转移。但过高的辐射会伤害到人体的健康细胞。因此,放疗中会使用保护块(shielding block)来保护健康部位。这些保护块往往用铅制成,可以吸收辐射,就像是特殊形状的"遮光板"。医生在进行放疗前,必须模拟和计算。根据癌细胞的位置和症状,确认病人接受放疗的姿势和保护块(shielding block)的形状和位置,然后计算出合适的辐射量(radiation dose)。这些计算和模拟都相当的复杂,细微到要考虑到皮肤对射线的反射。所以看似简单的放疗计划,需要一个团队的人来合作。随着计算机的发展和成熟,这些过程都逐渐由计算机接管,以及相关的TPS系统,用来处理上面的步骤。

 

巴拿马辐射事故的问题出现在向计算机输入保护块参数的这一步。

 

如下图所示,方形框代表伽玛射线照到病人皮肤上的区域。医生在方框内放上保护块(灰色区域),以保护健康组织。为了达到最好的效果,计算机需要知道保护块的大小和形状,以便能计算出最优的辐射量。定性的说,当保护块较大时,更多的辐射会被保护块吸收,也就可以用更大的辐射量对病人进行放疗。ION使用的TPS系统允许输入最多四个保护块的坐标:

图1 四个三角形

图中的四个灰色三角形为保护块位置,而被截剩下的方形中央是辐射区域。所以依次在四栏中输入各点坐标:

保护块1:1,2,3,1

保护块2:4,5,6,4

保护块3:7,8,9,7

保护块4:10,11,12,10

 

当然也可以如下图只使用一个方形的保护块,这时只需要保护块1栏中输入 1,2,3,4,1各点的坐标

图2 一个长方形

 

在事故之前几个月,医生希望使用多达5个保护块,以便能更好的保护重要器官。TPS系统只允许输入4个保护块的坐标。一开始的解决方法是直接使用第五个保护块,而不将这个保护块纳入到计算中。所以计算出并使用的辐射量比实际的最优解要小,所以这是一种安全的做法,但医生不满意系统的误差,他们希望使用“最优”的辐射量。为此,医院的技术人员“创造性”的发明了新的输入方法:

图三 致命方法 4个三角形

也就是,输入 保护块1:1,2,3,4,5,6,7,8,9,10,11,12,1。也就是先走完内圈的坐标,再接着走外圈的坐标,最终回到起点。医院的技术人员人为,这样作出的一个保护块形状和输入四个保护块的形状相同。依据上面的“方法”,5个保护块可以以下图方式输入(实际上,你可以构造出更多的保护块)。

 

 

图四 致命方法 4个三角形+1个长方形

技术人员很为自己的创造性开心,而医生则高兴的接受了这种看上去很“优雅”的输入方式。一拍即合之下,医院的所有放疗都采用了新式的输入方法 (即使是不需要五个保护块的病人)。从2000年8月到2001年3月间的放疗病人,医院都采取了这样的输入,直到医生终于发现患者实际上接受了致命的放射量。事实上,使用上述的输入方法算出的辐射量,会大大超过真正的辐射量(正确量的两倍以上)。键盘成为了死神的镰刀。

 

国际原子能机构(IAEA)对事件作出了调查,方法很简单,就是用不同的输入方法来做数值实验,对比计算出的的辐射量。事后发现,还是有幸运儿避过一难。按照上述方法输入整个保护块的坐标时,如果内圈和外圈反向,则计算的辐射量是正确的。

图5 幸运方法 反向内外圈

调查进一步发现,使用内外圈同向的输入方式,保护块的大小和形状对最终算出的辐射量几乎没有影响。比如下图的情况,理论上一个很小的在角上的保护块,与没有保护块的情况相比,结果应该相似。但实验结果显示,这样算出的辐射量并不相似于没有保护块的解,反而与图三、四相似。

图六 致命方法

到现在为止,我们已经可以大致可以勾勒出软件出现的问题了。当内外圈同向的时候,无论是图三、四还是图六,路径会沿着整个方形闭合,所以计算机认为整个方形都是保护块,因此肆无忌惮的增加辐射量。而内外圈反向,如图五的情况,路径不会沿着方形闭合,所以不会出现类似错误。以上结论是我自己的推断,而国际原子能机构中的结论只是说内外圈同向的输入成为一个保护块的方式会带来错误,并没有公布软件的内部构造。

国际原子能机构的数值实验方法并不复杂,医院的技术人员完全用相同的方法验证“创新”输入法。或许其它的bug可以在遇到实际问题时,被错误驱动着去修正。只是这一次,对象不是可以重启的计算机,而是真实的生命

 

放疗系统的软件设计有缺陷,理想的软件应该禁止不合法的输入方式。好的软件设计应该限制软件的自由度,并强制进行一些合法性检查。显然,Multidata公司做的并不完美。但值得欣慰的是,该系统的手册中明确建议使用人员核实辐射量,从而软性预防可能的错误。相同的系统在美国已经被广泛使用,并没有出现事故。在美国,人为失误造成的医疗事故会是重罪,所以医生和操作人员都有严格的流程。法院在判词中特别提到这一点,认为医院的医生和技术人员在“创新”之后没有核实结果,应该为此次事故负主要责任。

 

具有讽刺意味的是,医院的负责人由于“背景”深厚,并没有受到惩罚。

开发公司对老的系统发布了补丁。

 

附录:下面的bug可能无法事后修正

欧洲ARIANE 5火箭第一次发射,于一分钟之内爆炸。导航程序中的一个浮点数要转换成为整数,但由于数值过大溢出

 

英国Chinook直升机于1994年坠毁,29人死亡。调查显示,软件系统“充满缺陷”。

 

电影《2001太空漫游》中,超级计算机HAL杀死了几乎所有的宇航员,原因是HAL的两个目标出现了冲突:1. 不能透露任务内容;2. 不能对人类隐瞒信息

 

2002年,美国商业部报告估计,美国每年由于软件bug造成的经济损失为: 590亿美元

 

再次谢谢一只游泳的鱼的启发。

posted @ 2012-11-08 22:20  Vamei  阅读(6221)  评论(13编辑  收藏  举报