前一陣iPhone變磚問題引起很多人的關(guān)注,還有好奇寶寶去嘗試,結(jié)果......
有一種Bug叫時間Bug,現(xiàn)在,我們來解析下,那些讓計算機(jī)難以理解的人類的時間計算問題。
20世紀(jì)后期,全世界都沉浸在對21世紀(jì)的希望和憧憬之中。但是,關(guān)注計算機(jī)的人們卻在為一個問題大傷腦筋,就是計算機(jī)系統(tǒng)將2000年當(dāng)作1900年處理的“Y2KBug”(千年蟲)難題。“末日論”擁護(hù)者們甚至擔(dān)心計算機(jī)會全體罷工,而人類則走向滅亡。好在人們事先考慮到了這個問題,并做出了應(yīng)對措施,這才安然無恙地迎來了新千年。
正如在陽光強(qiáng)烈的白晝看不到星光一樣,與時間有關(guān)的Bug中,Y2KBug太有名了,以至于其他事件在它面前都不足以成為人們茶余飯后的談資。但事實(shí)上,和時間有關(guān)的Bug是軟件誕生以來最為頻發(fā)的Bug類型之一。自軟件誕生起到現(xiàn)在,仍然不時有此類Bug發(fā)生。與時間有關(guān)的Bug類型主要有:對閏年現(xiàn)象處理不當(dāng)導(dǎo)致的Bug、Y2KBug、源于計算機(jī)結(jié)構(gòu)的先天性Bug等。
閏年
雖然人們常說1年有365天,但事實(shí)上,地球圍繞太陽公轉(zhuǎn)一周所用的時間并非365天,嚴(yán)格來說需要365天5小時48分46秒。公歷上減去365天后,余下的時間約為4年累計1天,故每4年于2月加1天,變?yōu)?9天,使當(dāng)年的長度為366天,該年就為閏年。
但是,規(guī)定每4年必須有一閏年的日歷是儒略歷,其制定者就是說出那句“布魯圖斯,連你也……”名言的羅馬的尤利烏斯·愷撒。不過,儒略歷隨著時間的推移會產(chǎn)生一定誤差。而彌補(bǔ)這一缺陷的便是現(xiàn)在大多數(shù)國家正在使用的格里高利歷,其制定者是教皇格里高利十三世。
儒略歷規(guī)定4年一閏。也就是說,400年中有100年是閏年,且400年中共增加100天。這種方法雖然可以糾正地球公轉(zhuǎn)引起的偏差,但還不夠精確。而彌補(bǔ)了這一點(diǎn)的格里高利歷中,400年間,閏年只有97次,比儒略歷少了3次。這樣人們在時間的計算上就精確多了,但與4年無條件有1次閏年的儒略歷相比,它的閏年計算方法更為復(fù)雜。
以下是計算閏年的公式:
- 可以被4整除的年份是閏年(2008年、2012年、2016年……)
- 其中能被100整除的年份為平年(2100年、2200年、2300年……)
- 平年中可以被400整除的年份是閏年(1600年、2000年、2400年……)
如果隨便問一個路人什么是閏年、如何計算閏年,十個人中有九個會答不上來。因?yàn)橛嬎愕墓奖旧肀容^復(fù)雜,而且就算不知道也不會影響自己的日常生活。不知計算機(jī)程序員是否也沒將這個問題放在眼里,從而忽略了和閏年相關(guān)的軟件Bug,導(dǎo)致其成為軟件Bug界的“常客”。
微軟的野心之作與閏年Bug
已經(jīng)去世的史蒂夫·喬布斯被人們稱為“創(chuàng)新符號”和“怪才”,他回歸“蘋果”公司后取得的首次巨大成功就是便攜式媒體播放器(一般稱為MP3播放器)——iPod。看到這款產(chǎn)品在世界范圍內(nèi)掀起了一股風(fēng)潮,而且銷量驚人,全世界的家電企業(yè)都開始進(jìn)軍便攜式MP3播放器市場。在便攜式媒體播放器領(lǐng)域從未嘗到過甜頭的三星公司曾經(jīng)將便攜式MP3播放器領(lǐng)域的管理部門作為子公司分離了出去,在iPod風(fēng)潮的沖擊下,三星公司重新合并了子公司,決定向該領(lǐng)域發(fā)起沖擊。
軟件公司微軟也不想錯過“這塊蛋糕”,推出了名為“Zune”的產(chǎn)品,想要制衡“蘋果”公司。
但是,曾通過推出Windows而壟斷個人計算機(jī)操作系統(tǒng)的微軟在iPod面前也敗下陣來。禍不單行,美國當(dāng)?shù)貢r間2008年12月31日0時起,微軟公司30GB 版Zune音樂播放器同時出現(xiàn)了大規(guī)模的無法啟動故障。微軟公司發(fā)布聲明稱:“正在努力解決這個問題,將會通過Zune官方網(wǎng)站盡快公布解決方法。”為控制事態(tài)發(fā)展,微軟可謂大傷腦筋。
其實(shí),原因就出在閏年上。Zune中內(nèi)置的日期計算軟件計算當(dāng)前日期時,閏年計算出現(xiàn)錯誤,導(dǎo)致機(jī)器無法啟動。既然找明了原因,解決起來就容易了。出現(xiàn)故障24小時后,2009年1月1日,日期不同了,年份也變了,Zune也就恢復(fù)了正常。
之后,微軟到2011年為止又相繼推出多款產(chǎn)品,但最終都沒能超越iPod。終于,2011年3月,微軟宣布停止生產(chǎn)Zune 播放器。
讓全世界游戲玩家備受煎熬的PS3閏年Bug
2010年3月1日,日本索尼公司的電視游戲機(jī)Play Station3(以下簡稱PS3)出現(xiàn)了死機(jī)現(xiàn)象。出現(xiàn)問題的并非當(dāng)時最新款的PS3薄版,而是舊版PS3。這個故障使全世界眾多玩家一整天都沒能玩到游戲。而這天是韓國的公休日(三一節(jié)),正是玩游戲的大好時間,所以韓國的玩家們才更倒霉。很多韓國玩家這一天只能對著屏幕上的故障畫面發(fā)呆、抓狂。
2010年3月1日啟動PS3 后,韓國等亞洲國家的時間會變更為2000年1月1日,而美國等北美國家則變?yōu)?999年12月31日。而且玩家無法聯(lián)網(wǎng),達(dá)到一定等級后積累的個人游戲記錄和名下的獎品亦告消失,同時屏幕彈出“獎品信息登錄失敗。游戲結(jié)束。(8001050F)”的消息。這個故障也是閏年Bug引起的。到了第二天,3月2日,問題自動解決,機(jī)器又恢復(fù)正常。
醫(yī)院系統(tǒng)故障,紙筆代替電腦
1989年9月19日上午,位于賓夕法尼亞州的醫(yī)療共享系統(tǒng)(Shared?Medical Systems,以下簡稱SMS)公司的電話鈴聲此起彼伏。打電話的雖然不是同一個人,但說的話都一樣:
“醫(yī)院系統(tǒng)停止工作了。”
這一天,美國全境一百多家醫(yī)院不得不放棄之前一直使用的計算機(jī)系統(tǒng),改為用紙筆記賬。使用SMS提供的軟件和系統(tǒng)的所有醫(yī)院都出現(xiàn)了這樣的情況。SMS技術(shù)人員認(rèn)定這是突發(fā)狀況,作為權(quán)宜之計,他們建議所有醫(yī)院都關(guān)閉計算機(jī),然后開始尋找事故原因。
幾小時后,人們查明了原因。SMS開發(fā)的軟件出現(xiàn)錯誤,計算機(jī)無法識別1989年9月19日這個日期,所以出現(xiàn)故障。那為什么是9月19日呢?原因就在于16位數(shù)據(jù)結(jié)構(gòu)。當(dāng)時醫(yī)院使用的電腦是以1900年1月1日為起點(diǎn)計算日期的。故障發(fā)生的1989年9月19日在起點(diǎn)基礎(chǔ)上又過了32 768(即215)天,已經(jīng)超出了16位數(shù)據(jù)結(jié)構(gòu)可以承受的數(shù)字范圍0~32 767。因此,計算機(jī)無法識別這個數(shù)字,系統(tǒng)就出現(xiàn)故障。
這次故障并沒有造成數(shù)據(jù)丟失或者醫(yī)療器械停止工作從而危及患者生命的事故,但另一個不能忽視的問題是,今后仍然存在發(fā)生此類問題的隱患。尤其是現(xiàn)在大多數(shù)服務(wù)器都在使用的Unix 操作系統(tǒng)在時間計算上還存在著以下問題:SMS的計算機(jī)系統(tǒng)時間起點(diǎn)是1900年1月1日,而Unix是以1970年1月1日為起點(diǎn)計算日期的。Unix在此基礎(chǔ)上加上系統(tǒng)時間(秒)計算日期,但問題在于,保存系統(tǒng)時間的數(shù)據(jù)類型是“32位帶符號整數(shù)”。
32位帶符號整數(shù)可以存儲-231~231-1的數(shù)字,也就是-2 147 483 648 ~2 147 483 647。1970年1月1日0時00分,在UTC的基礎(chǔ)上再過2 147 483 647 秒就是2038年1月19日3時14分7秒(UTC)。從這一刻起再過1秒,也就是2038年1月19日3時14分8秒開始,系統(tǒng)存儲的時間值不是從2 147 483 647 變?yōu)? 147 483 648,而是變?yōu)椋? 147 483 648。
因?yàn)榇鎯r間值的空間只有32位,所以無法存儲2 147 483 648 這個數(shù)字。這樣,從2038年1月19日3時14分8秒(UTC)開始,Unix操作系統(tǒng)會將當(dāng)前時間計算為1901年12月13日20時45分53秒(UTC)。如果不盡快解決此問題,類似事件將會重演。
解決的方法其實(shí)很簡單。只要將系統(tǒng)時間從現(xiàn)有的帶符號32位整數(shù)擴(kuò)大到64位或者128位即可。當(dāng)然也不能盲目擴(kuò)大,因?yàn)檫@涉及與時間改變相關(guān)的代碼兼容問題。最近開發(fā)的64位操作系統(tǒng)中,存儲時間的數(shù)據(jù)類型使用的都是64位帶符號數(shù)。使用64位帶符號數(shù)后,可以表示的最后時間是292 277 026 596 年12月4日(約2920億年)。但與現(xiàn)有代碼實(shí)現(xiàn)兼容的常規(guī)解決方案尚未出現(xiàn)。
罷工的導(dǎo)航儀
2012年3月31日,美國、澳大利亞、英國等地使用的TOMTOM導(dǎo)航儀突然停止工作,屏幕上出現(xiàn)“無法連接到GPS衛(wèi)星”的消息,此外不顯示任何信息。幾天后,TOMTOM的生產(chǎn)廠家發(fā)布了用于修復(fù)的補(bǔ)丁程序。引起這次故障的元兇就是GPS接收器所用的軟件。軟件出現(xiàn)閏年Bug,使整個導(dǎo)航儀變?yōu)闊o用之物。本來TOMTOM 就在與智能手機(jī)內(nèi)置導(dǎo)航系統(tǒng)(谷歌地圖等)的競爭中節(jié)節(jié)敗退,苦不堪言,這次事件讓他們又挨了當(dāng)頭一棒。
日常生活中的Y2KBug
1992年的一天,美國的瑪麗·班達(dá)爾接到了去明尼蘇達(dá)州威諾納的幼兒園上學(xué)的通知。但是,出生于1888年的瑪麗·班達(dá)爾在1992年已經(jīng)104歲了。這是一個典型的Y2KBug。計算機(jī)只處理了出生年份四位數(shù)中的后兩位,以此為標(biāo)準(zhǔn)尋找學(xué)齡前兒童,所以才發(fā)生了這樣的怪事。
布洛杰特101歲時,他的汽車保險費(fèi)突然上漲了3倍!查明原委后發(fā)現(xiàn),還是Y2K問題在作怪。電腦竟然將布洛杰特的年齡識別為1歲。這次的Y2K問題還牽出了之前一直未引起人們注意的政策性錯誤:20歲以下一律視為青少年,所以汽車保險費(fèi)上漲了3倍……等等,1歲也算是青少年嗎?
寫給軟件開發(fā)者的話
Zune 媒體播放器的用戶論壇ZuneBoard 上,有人提出,2008 年12 月31 日發(fā)生的硬件故障來自Zune 的時鐘驅(qū)動器。ID 名為“isnotabigtruck”的用戶在網(wǎng)站公布了飛思卡爾處理器的時鐘驅(qū)動源代碼,并做出說明:“Zune 在啟動過程的最后一個階段第一次訪問時鐘驅(qū)動,將時鐘變更為日期和時間。” 他給出的下列代碼是從日期中計算年份。
請留意第9行代碼。2008年是共有366 天的閏年,2008年12月31日是2008年的第366天。days 變量中輸入366后,第9行的if語句會判斷為false,然后移動到第20行。而days變量仍然是366,這樣就會進(jìn)入無限while 循環(huán)。
以上是飛思卡爾MC13783PMIC 處理器的驅(qū)動代碼。當(dāng)時,使用該處理器的東芝公司的Gigabeat S媒體播放器也曾出現(xiàn)類似情況。
本文選自《致命Bug》。
作者:金鐘河
譯者:葉蕾蕾
《致命Bug》通過軟件史上的經(jīng)典案例,介紹了軟件故障引發(fā)的宇宙、航空、軍事、通信、金融、醫(yī)療、生活等多領(lǐng)域的事故。即使不具備軟件相關(guān)的專業(yè)知識,平時關(guān)注歷史事件或熱點(diǎn)話題的普通人也能受益匪淺。尤其是希望編寫無Bug軟件的開發(fā)人員或測試人員、經(jīng)營軟件公司的管理人員或高層人士等,更能從本書中獲得豐富感受。
點(diǎn)擊書名查看完整目錄與試讀。