抗日的理論基礎

來源: 事後諸葛 2013-11-04 18:49:52 [] [舊帖] [給我悄悄話] 本文已被閱讀: 次 (25098 bytes)

轉貼自:http://club.tgfcer.com/thread-6817371-1-1.html 網友Kuzuryuusen的文章

----------------------------
【第一部分】背景簡介



前幾年鬧得沸沸揚揚的豐田刹不住事件最近又有新進展。十月底俄克拉荷馬的一次庭審
,2007年一輛2005年凱美瑞暴衝(Unintended Acceleration,UA)致一死一傷事件中
豐田被判有責。引起廣泛關注的是庭審中主要證人Michael Barr的證詞讓陪審團同意豐
田的動力係統軟件存在巨大漏洞可能導致此類事件。這是豐田在同類事件中第一次被判
有責。庭審過後豐田馬上同意支付300萬美元進入調解程序。

出於好奇,我漫不經心地下載了Barr的286頁證詞,卻一下子被吸引住了。幾天內讀完
,算是對這次事件進行了一次深入了解。下麵就從外行角度總結一下這份證詞並嚐試以
更簡單的語言解釋裏麵提到的暴衝原因以及豐田犯下的錯誤。

Barr的證詞下載自他的個人博客Barr Code,但現在該文已經被刪除。稍後找地方上傳。

Michael Barr是誰?他是一位擁有20年以上行業經驗的嵌入式係統工程師。在十八個月
中,有12位嵌入式係統專家,包Barr,受原告訴訟團所托,被關在馬裏蘭州一間高度保
安的房間內對豐田動力控製係統軟件(主要是2005年的凱美瑞)源代碼進行深度審查。
這房間沒有英特網,沒有手機信號,他們進出不能攜帶任何紙張、記錄甚至皮帶。最後
的調查結果被寫入一份800頁,13章的詳細報告。而鑒於保密協議,調查內容一直沒有
公布,直至俄克拉荷馬這次庭審才首度部分公開(報告本身似乎還沒公開)。

回到正題。豐田的軟件有沒有缺陷?根據Barr的調查,答案是有。這其實是廢話,任何
軟件都會有缺陷,關鍵在於是什麽樣的缺陷。豐田的軟件缺陷分為三類:

非常業餘的結構設計。
軟件設計的基本要求是模塊盡量簡單化,因為這樣可以一來更易於閱讀二來更易於維護
。但豐田的工程師顯然沒有遵循這原則。Barr使用一種工具自動根據代碼的可能分支數
量評估函數的複雜度,結果是豐田的軟件中至少有67條函數複雜度超過50,意味著運行
這個函數可能出現超過50種不同的執行結果,屬於“非可測”級別。因為為了測試這50
個不同的結果,必須準備至少50條不同的測試用例以及相應的文檔,在生產環境中一般
是不現實的。作為比較,Barr表示他自己的公司嚴格執行的其中一條規定就是任何代碼
複雜度不能超過30,否則不合格。而在這67條函數中還有12條複雜度超過100,達到“
非可維護”級別,意味著一旦發現缺陷(Bug)也無法修複,因為實在太複雜,修複缺
陷的過程中會產生新的缺陷。其中最複雜的一條函數有超過1300行代碼,146個可能執
行路徑——正好用於根據各傳感器數值計算節氣門開關角度。
如果你不知道什麽是節氣門,那麽這裏我稍微解釋一下。為了讓內燃機運行,有三大要
素:燃油、空氣和點火時機。空氣和燃油的混合物進入氣缸,被火花塞在正確的時間點
燃推動活塞並最終推動曲軸和車輪前進。在電噴技術發明以後直到2002年以前,三大要
素的燃油和點火時間是由電子設備控製,節氣門機械連接加速踏板,由司機直接控製。
節氣門大致是一個連接加速踏板的“空氣龍頭”——踩下去越多,“龍頭”打開得越大
,允許越多的空氣進入發動機輸出更大的動力。2002年以後,豐田引入的“電子油門”
讓電子係統掌管了最後一個要素:空氣。加速踏板不再機械連接節氣門,而是連接一些
傳感器,由行車電腦將這些傳感器數值計算成節氣門開啟角度再由馬達控製節氣門。我
們稍後會再討論節氣門開合。
極複雜的代碼帶來的是極複雜的功能。下麵說一下被稱為“廚房洗滌盆”的Task X。這
裏先解釋一下,豐田的軟件係統和很多別的軟件係統一樣,都是由一個統領程序(稱之
為“操作係統”)和若幹小程序(稱之為Task)組成。就好比電腦上跑的Windows是統
領全局的操作係統,網絡瀏覽器和記事本是跑在操作係統上的小程序。豐田的係統裏每
個Task都有自己的名字,但這些名字非常敏感,敏感到每次被提及的時候律師都要求法
庭內的沒有閱讀代碼權限的人全部清場。為了減少清場次數,Barr將這個最重要的小程
序稱為Task X。這個Task X有多重要呢?跟廚房裏的洗滌盆一樣重要。它負責非常多的
事情,包括計算節氣門開啟角度、速度監測和保持、定速巡航監測等等。Task X的不正
常運行被認為是暴衝事件的元凶。稍後會再繼續討論Task X。
還有一些別的匪夷所思的發現。比如豐田的軟件包含了超過一萬一千個全局變量。如果
你不知道什麽是全局變量,那麽隻需要知道軟件設計的一般原則是要盡量少使用全局變
量,因為有可能帶來無法預測的結果。這裏的“少”的意思是“盡量接近零”,絕對不
會是一萬一千個。
不符合軟件開發規範。
如同很多行業一樣,汽車行業也有自己的規範。更具體一點,由於汽車的危險性質,汽
車控製係統被劃分為“安全關鍵性係統(Safety Critical System)”——說白了就是
安全性非常重要,弄不好會死人的。為了達到這一特殊要求,汽車相關軟件開發人員定
期舉行會議討論並發布編程規範,稱為MISRA C。該規範的2004年版的感謝列表裏還能
看到豐田員工的名字,至少讓外界認為豐田確實也在遵循這些規範。
真的嗎?根據源代碼來看,答案是否定的。對此之前的NASA報告也有所提及,豐田辯稱
他們遵循的不是行業規範,而是豐田內部編程規範。這一規範與行業規範的吻合程度達
到50%。但是Barr認為根據他的調查,兩個規範之間吻合度小於10%,甚至有若幹規範條
目相互衝突。後來發現豐田的代碼甚至沒有遵循豐田內部規範,當然比起別的問題這個
已經無關緊要了。
MISRA C擁有超過100條規範,NASA的調查隻使用了到其中35條進行校對,發現超過7000
處違規代碼。Barr使用全部條目,對照結果是豐田的程序擁有超過80000處違規代碼。
這些數字說明了什麽?根據統計,違規數量可以用於預測代碼中暗藏的缺陷(Bug)數
量。在之前提到的汽車相關軟件開發人員會議中,有人就這一主題發表過專題演講,提
出每30處違規代碼可能包含一個重大缺陷和十個輕微缺陷。諷刺的是這人是豐田員工。
特別需要指出MISRA C其中一個規則的內容是不得使用遞歸。
如果你不知道什麽是遞歸,那麽這裏我稍微解釋一下。遞歸是一種計算方法。但一般計
算方法要麽是自己算,要麽詢問別的計算模塊索要結果。而遞歸則是通過問一層層問自
己的方法完成計算。好處是代碼簡單,壞處是計算層數不固定。可能會2層就出結果了
,也可能會是10000層,在設計程序的時候無從得知。
軟件計算需要消耗存儲器。越繁瑣、越長的計算自然需要占用越多的存儲器。遞歸的問
題在於其嵌套層數無法預測,從而導致可能消耗的存儲器容量無法控製。稍後會再討論
存儲器。
對關鍵變量缺乏保護。
什麽是變量?變量就是存在一段存儲器的0和1的集合。這些變量既可以是一些函數的處
理結果,也可以是另一些函數的處理原材料。比方說前麵提到有一條程序專門計算節氣
門開合角度,比如說是20度,這個20就是一個變量,存在存儲器的一個指定位置。另一
個程序專門負責開合節氣門,它知道去那個指定位置讀取這個20,然後把節氣門開啟20
度。
什麽是保護?嵌入式係統,或者任何係統,都會在一定條件下發生硬件或者軟件錯誤。
客觀上這是無法避免的。而且汽車作為一個時常在震動、發熱、位移的係統,它的內部
環境不能說不惡劣,發生硬件錯誤的可能性甚至更高。什麽樣的硬件錯誤呢?別忘了變
量都是0和1的組合,這些0和1由存儲器上的高低電平代表。由於某些不可抗原因,一個
電平從高變成低,或者反過來,那麽這個變量就被更改了。這被稱為“位反轉(Bit
Flip)”。為了對抗這樣的事情發生,需要對變量進行保護。保護的方法一般是鏡像法
。簡單來說就是在兩個不同的地方寫入同一個變量,讀取的時候兩邊都讀,比較是不是
一致。如果不一致,那麽可以得知這個變量已經不可靠,需要進行容錯處理。
豐田的程序總體上對其上萬個變量進行了有效保護,但問題出在操作係統上。前麵提到
豐田的軟件本質上分為操作係統和Task。Task是由豐田自己開發,但是操作係統則是由
芯片供應商提供,固化在芯片裏的。豐田在這裏的過失是沒有對供應商提供的代碼進行
深度審核,拿到什麽用什麽。
另一個保護措施是錯誤校驗碼(Error Detective and Correction Codes,EDAC)。這
是一個硬件層麵的數據保護措施。簡而言之就是給內存中每一個字節(8比特)後麵物
理地增加幾比特校驗碼。這樣萬一變量出錯了,可以通過校驗碼得知,甚至可以通過校
驗碼修複一些輕微錯誤。這個措施十分簡單有效,但是在2005年款凱美瑞的係統中完全
沒有使用,豐田卻告訴NASA他們用了。而在2008年款凱美瑞中使用了3比特長的EDAC。
Barr認為是為了節省成本,否則應該使用5比特長。
還有值得一提的是,汽車相關的軟件行業有那麽幾家操作係統供應商,早已形成了一套
成熟標準稱為OSEK。各供應商開發的符合OSEK認證的操作係統至少都能達到一定的質量
。但豐田選用的操作係統卻沒有通過認證,讓人不解。


現在我們知道豐田在編寫軟件的時候至少有三種缺陷。那麽重點問題:豐田的這些軟件
缺陷是否會導致車輛暴衝?根據Barr的調查,答案是有可能。暴衝的起因需要結合上述
三種缺陷來說明。

汽車正常運行需要倚靠若幹程序(這裏叫Task)的同時運作。Task有很多,CPU隻有一
塊,在任何時刻隻能處理一個Task,怎麽辦呢?這需要操作係統的統籌規劃,合理分配
CPU的任務,讓每個Task都能按時執行。如果出現某種意外,讓某個Task突然不執行了
,那麽就稱為這個Task“死亡”。Task死了,自然不能執行它的任務。根據Barr的測試
,在某些特定情況下,Task X的死亡可以導致節氣門敞開——因為Task X的其中一個任
務就是根據司機的操作計算節氣門開合角度,它死了也就沒法重新計算這個角度,即使
司機把腳挪開加速踏板,節氣門也無法關閉。此為暴衝的直接原因。更糟糕的是,節氣
門的開合角度這個數值,被Task X算出來以後保存在一個變量中。這個特定的變量正好
沒有被保護(缺陷3)。意味著萬一Task X死亡並且停止計算,這個數值有可能因為不
可抗原因被改變,而程序無從得知。

那麽Task X為何會死亡呢?一般是因為內存出錯。這個出錯可能是一個小小的位反轉,
也可能是內存裏的數值被別的程序錯誤覆蓋。同一係統內同時運行了若幹程序,這些程
序需要共享一塊內存,內存內部必然要被劃分成若幹塊。比如第一塊給程序1,第二塊
給程序2,等等。如果程序1因為某些原因(比如Bug)寫到第二塊內存上去,就會導致
程序2讀取了錯誤的信息。這就是所謂的內存出錯。豐田的係統裏,正好有這麽兩塊相
鄰的內存塊。第一塊被稱為“堆棧(Stack)”,這是所有Task存儲它們運行狀態的地
方,大小為4KB。與之相鄰的地方儲存了操作係統進行任務分配的記錄。那麽可以想象
,如果很多Task給堆棧裏寫入太多東西,超過4KB,那麽就會錯誤地寫入與之相鄰的任
務分配表。這種錯誤被稱為“堆棧溢出”。操作係統拿到了錯誤的任務分配表,就會錯
誤地分配任務,造成某些Task多執行幾次,某些Task少執行幾次,某些Task甚至就再也
不執行——死了!必須指出的是,程序死亡並不罕見,甚至可以認為是正常現象。稍後
解釋處理方法。

那麽堆棧為什麽會溢出呢?顯然是因為要寫入的數據超過了堆棧的容量。在設計程序的
時候要計算最壞的情況並且允許冗餘。即使作出了正確的設計,這種錯誤也相對常見,
所以NASA在他們的調查中重點排查堆棧溢出的可能性。於是NASA問豐田,豐田的回複是
最壞的情況下4KB堆棧隻寫入了41%的數據,換句話說發生溢出的可能性非常低。NASA直
接取信了這個數字並沒有再深入調查。但Barr他們發現豐田的回答有嚴重低估,實際上
最壞的情況會達到94%,而且還不算遞歸。豐田在代碼中使用了遞歸(缺陷2)。因而實
際數字有可能超過94%而且無法預計上限,因為遞歸計算的嵌套層數是無法預測的。所
以實際情況下堆棧溢出的可能性相當可觀。一旦溢出,相鄰的任務分配表不可避免就會
遭到破壞。此為暴衝的根本原因其中之一。之所以說“其中之一”,是因為堆棧溢出僅
僅是損壞任務分配表的其中一個原因,別的還有許多可能性並沒有被Barr在法庭上深入
解釋。而且任務分配表的損壞也僅僅是導致Task死亡的原因之一。
順便提一句,2005年的凱美瑞的這部分供應商是電裝,沒有搭載堆棧實時監測功能——
溢出了也不知道。同年的卡羅拉卻搭載了,因為供應商是通用。


到這裏我小結一下,串鏈子。左邊是原因,右邊是後果。
堆棧溢出→(可能導致)→任務分配表被改寫→(可能導致)→Task X死亡→(可能導
致)→節氣門敞開→(導致)→汽車暴衝

必須指出的是,這條鏈子從最左邊一直到Task X死亡,都還算是嵌入式係統的常見故障
。雖然程序代碼寫得不好也許導致更容易出錯,客觀上豐田並沒有特別大的過錯。隻要
處理得當,這些故障都不會導致暴衝。

到此為止還隻是前奏而已,接下來我們來看看豐田到底做錯了什麽。

【第二部分】豐田之罪

上麵反複提到,嵌入式係統中內存出錯或者程序死亡其實是一種正常現象——至少從
Barr的證詞可以得出這個結論——現在連我們都知道了,嵌入式工程師肯定比我們更清
楚才對。確實,為了使係統正常運行不被錯誤幹擾,一般的做法是設置若幹層防護措施
(Failsafe),讓運行中出現的錯誤無法輕易突破,得到妥善處理。豐田的工程師自然
也懂得這一點。很可惜,他們搞砸了。

上麵那條鏈子應該修改成這樣:
(防護措施0)→堆棧溢出→(防護措施1)→(可能導致)→任務分配表被改寫→(防
護措施2)→(可能導致)→Task X死亡→(防護措施3)→(可能導致)→節氣門敞開
→(防護措施4)→(導致)→汽車暴衝

可以看到,防護措施不可謂不多。隻要處理得當,這鏈條應該是走不通的。現在讓我們
從左到右看一個小小的內存錯誤是如何一層層突破防護最終導致汽車暴衝的。

首先防護措施0。這個其實上麵提到了,因為設計缺陷低估了最大占用的存儲容量,並
且不符合規範地使用了遞歸,最終可能導致堆棧溢出。

然後到防護措施1。上麵也提到了,任務分配表緊鄰堆棧。作為外行我都覺得這是個十
分危險的設計——既然堆棧這麽容易溢出,好歹應該將任務分配表放遠一點啊。當然我
是外行,可能實際上比想象中複雜很多。這段Barr的證詞中並未特別提到,屬於我的個
人理解。

防護措施2。從這裏開始豐田的錯誤越發嚴重。任務表被改寫導致某些Task運行異常,
在軟件層應該有若幹檢測措施,比方說用特殊的監視Task來監視別的Task是否正常。但
豐田是怎麽做的呢?還記得上麵的“廚房洗滌盆”Task X嗎?它是如此複雜(缺陷1)
,除了控製汽車運行的任務之外竟然還兼任大部分的監視任務,比如生成DTC。
DTC(diagnostic trouble codes),是汽車電腦係統會根據情況生成的錯誤代碼。有
的車主可能會遇到汽車某報警燈常亮,修車師傅拿個儀器插在行車電腦上得出一個代碼
,再查表就知道哪個元件壞了——這就是DTC。除了用於修車,DTC還被用於檢測行車電
腦和各傳感器的異常狀態。
可以想象,這個既是運動員又是裁判的Task X一旦死亡,軟件層的檢測措施大部分就失
效了。

防護措施3。在這裏豐田的錯誤開始到達頂峰。即使設置正確無誤,上麵提到的監視
Task也隻不過是另一個Task而已,與它的監視對象算是平級——監視Task自己同樣有可
能出現故障。嵌入式係統的一般做法是在所有程序之上再設置一道屏障,被稱為“看門
狗(Watchdog)”。所謂看門狗,是一個優先級很高的倒計時程序。別的程序需要在運
行的時候特意去重置一下這個計時器讓它重新開始倒計時,這個動作被稱為“喂狗”。
如果因為程序出問題太長時間不喂狗,倒計時完成,看門狗知道什麽地方卡住了,馬上
采取措施,比如重啟整個係統。重啟係統聽起來似乎很嚴重,實際上卻是一件相當普通
的事情。嵌入式係統的重啟非常快,時速100公裏的汽車中動力係統可以在半米之內完
成重啟——車上的人根本覺察不到。
通過閱讀代碼和擬真實驗,Barr驚訝地發現上述嵌入式係統的常識性做法竟然在豐田軟
件係統內不存在!豐田的軟件確實有一隻看門狗,但它竟然不是用於監視Task異常,而
是用於防止CPU過載。首先這個做法不能說後無來者至少算是前無古人。還記得上麵提
到的800頁13章的報告嗎?目瞪口呆的Barr將豐田看門狗的分析結果寫入了報告的第一
章,因為他實在太震驚。其次,豐田看門狗的防止CPU過載功能也相當蹩腳,在擬真測
試發現即使它正常工作,還是會允許CPU過載時間長達1.5秒——時速100公裏的車能跑
40米以上。CPU一旦過載,就會導致所有的Task進入一種“假死”狀態,無法處理信息
,這時司機無法控製汽車動力,十分危險
另外,豐田的工程師還犯了一個嵌入式課堂上被反複提到的經典錯誤:使用硬件時鍾中
斷喂狗。硬件中斷擁有非常高的優先級,即使Task卡住(比如出現死循環)也不能阻止
硬件中斷——可想而知這樣一來看門狗就等於完全白瞎了。
這裏也提一句,同年的普銳斯卻令人意外地搭載了一隻運作正常的看門狗,反而讓人摸
不著頭腦。
還沒完。這一層防護是嵌入式係統的關鍵陣地。前麵都是電子係統,後麵馬上進入機械
運作,足以造成災難了。所以僅僅擁有軟件級別的防護還不足夠,豐田的做法是在主
CPU之外單獨設置了一塊監視芯片,從硬件級別對係統的運作進行監視。監視芯片有兩
個任務。第一,它運行一種叫做係統衛士(System Guard)的程序,原理上來說是專門
用於防止暴衝。主CPU和監視芯片上都會運行係統衛士,可是研究發現Task X一旦死亡
,這些係統衛士統統都不起作用了。第二,它運行一個被稱為“刹車回聲檢查(Brake
Echo Check)”的程序。這個程序從代碼上來看似乎可以檢測出Task X的死亡,並且采
取相應措施:關閉節氣門。聽起來像是好消息,但是同樣有問題:首先這個程序不太可
靠,即使正常運行,理論上也有失效的可能。最關鍵的是該程序不會自動運行,需要司
機先對刹車踏板有“動作”才會觸發。注意這裏我特意沒用“踩刹車”這個詞,因為根
據分析“觸發動作”十分令人困惑。它分兩種情況:如果Task X死亡的那一刻司機的腳
不在刹車踏板上,那麽觸發動作是踩刹車。還算可以理解。另一種情況,如果Task X死
亡那一刻司機的腳踩在刹車踏板上,那麽觸發動作是完全釋放刹車踏板。沒錯,察覺車
子在不正常加速的司機需要停止踩刹車才能讓控製係統關閉節氣門!這種違背人類認知
的行為應該不是豐田工程師特意設計的。如果是,他們到底在想什麽啊?
到此為止,上麵提到的都算是“戰術層麵”的錯誤,都是“小錯”。在講解這塊監視芯
片的時候,可以發現豐田犯下最嚴重的“戰略層麵”錯誤——基礎設計。Barr認為,如
果基礎設計正確,上述那些小錯都完全不會導致汽車暴衝——不管代碼寫得多業餘,不
管內存錯誤多嚴重,不管Task死得多頻繁,統統不會致命。讓我們回到2002年以前,沒
有電子油門的時候。那時候的拉線油門是由油門踏板機械連接的。當駕駛員的右腳踩下
刹車,他的右腳必然不在油門踏板上,節氣門自然而然地被關閉。這個動作如此自然,
甚至算不上安全措施,僅僅因為每人隻有一隻右腳,不可能同時踩油門和刹車。當豐田
設計電子油門的時候,隻要稍微有點常識,都應該從設計階段就將這一“自然而然”發
生的動作考慮進去。但是很顯然,他們沒這麽做。監視芯片上運行的代碼是用匯編語言
(一種更加接近機器執行代碼,遠離人類語言,更加難懂的編程語言)編寫的,運行層
次比主CPU的C語言更低。Barr認為如果設計得當,現有的監視芯片完全有能力勝任上述
功能,需要的僅僅是幾百行代碼,別的什麽都不用更改——不會提高任何生產成本。很
遺憾,他們沒有做到。


防護措施4。現在已經脫離電子係統,節氣門已經敞開,發動機全速運轉,需要使用機
械運作來組織機械運作了。如何讓向前衝的車子停下來?不開車的人都知道,刹車!現
代汽車都裝備了刹車助力,助力來自於發動機運轉的時候產生的負壓。我們知道發動機
需要吸入空氣,吸入體積等於排氣量乘以轉速。節氣門又是用來阻擋空氣的,那麽節氣
門關閉而發動機轉速相對高的時候(比如高速丟油門),發動機的實際空氣吸入量比它
能吸入的體積要少,那麽從節氣門到氣缸進氣口之間會形成明顯低氣壓(所謂負壓,比
大氣壓力小)。刹車助力就是利用了這個負壓推動氣鼓產生更大的推力帶動刹車片抓緊
刹車盤。但是如果節氣門敞開讓空氣隨便進來,低氣壓就不存在了,這時刹車助力大大
減弱,刹車效率也大大降低。這就是為什麽暴衝事件當事人都說全油門的時候根本刹不
住的重要原因。這個現象稱為“真空損失(Vacuum Loss)”,存在於所有自然吸氣的
汽油發動機汽車(柴油和增壓發動機沒影響),不算豐田的錯。但豐田遲遲不搭載刹車
優先係統(Brake Override System)允許刹車的同時敞開節氣門,毫無疑問是這個現
象的幫凶。
所謂刹車優先係統,指的是保證同時踩下刹車油門兩個踏板的時候無條件關閉節氣門的
功能。這麽做很顯然主要是為了降低發動機輸出,同時也保證刹車助力。豐田在2010年
的凱美瑞上終於搭載了刹車優先係統,但是別高興得太早。根據Barr的調查,豐田竟然
將如此重要的修改“理所當然”地寫入了他們的“廚房洗滌盆”——Task X。我隻能“
啞然失笑,扼腕歎息”。


好了,到此為止都還是Barr的一麵之詞,而且大部分都是在那間守衛森嚴的房間內進行
擬真測試得出的“理論結果”。那麽實車測試情況如何呢?豐田對Barr的證詞如何反駁
呢?


先說說實車測試。為了證明理論,他們把2008年和2005年的凱美瑞放在馬力機上,固定
車身架起前輪模擬車輛運行情況。他們的做法是首先讓車子運行在時速68英裏(110公
裏),啟動巡航,腳離開油門踏板。然後暫停巡航,速度開始下降。下降到一定程度恢
複巡航,速度開始上升。在到達68英裏的設定時速以前,他們用一台連接行車電腦的筆
記本“注入”錯誤。所謂注入錯誤,就是人為地翻轉一個特定字節——將0改成1,或者
反過來——模擬內存損壞。結果完全符合理論,時速超過68英裏也不停止加速,直至時
速90英裏(145公裏),測試人員踩下刹車。大約1秒以後節氣門被關閉,Barr認為這是
上述“刹車回聲檢查”的功勞。


實車測試證明了Barr的理論,卻並不是全無破綻。豐田辯護律師就兩點提出質疑:
實車測試使用人工注入錯誤的方法,並不能證明現實中這種錯誤就一定會發生。
對此Barr的回答是測試的局限性。因為測試時間、樣本有限,而待測試的樣本空間無窮
大。如果要等待那個特定的錯誤自然出現,可能需要成百萬上億小時的不間斷測試,顯
然是不現實的。更何況從科學上而言,沒有辦法對這個錯誤證偽——就好比無法證明宇
宙裏沒有外星人,最多隻能證明火星上找不到而已。但是這個測試足以證明一個小小的
位翻轉確實可以突破重重障礙最終導致暴衝,足以證明豐田的軟件存在不能容忍的隱患。
Bookout女士(本案原告)聲稱,在她駕駛汽車離開高速的時候發現不受控加速,她拚
命反複踩下刹車並且拉起手刹,現場留下了刹車痕跡。但並沒有跡象表明發動機動力中
斷——換言之“刹車回聲檢測”沒起作用。暗指Barr的理論站不住。
對此Barr的回答是首先盡管在實車測試中每次都生效,但代碼分析表明“刹車回聲檢查
”這一功能在理論上靠不住。其次這一功能的另外一個觸發動作是要讓腳完完全全離開
刹車踏板。試想車子正在不受控地往前衝,任何人都會不由自主地踩刹車,讓人完全不
踩刹車踏板根本就是違背認知的。Bookout女士即使如同她所稱反複踩刹車,很可能隻
是一直將腳放在踏板上往複運動,從未完全挪開。Barr還引用一位豐田自己的軟件專家
的證詞。該專家承認,如果發生暴衝的時刻腳正好接觸到刹車踏板,並且之後一直沒挪
開,那麽汽車的暴衝距離“取決於還剩多少汽油”。

最後順帶說一下那份800頁,13章的詳細報告完成後,Barr將其提交給了豐田的軟件部
門,等待他們的反駁。最終結果是“非常少(Very little)”,13章中的11章,包括
堆棧溢出的部分、代碼混亂的部分、違反開發規範的部分、Task X過於臃腫甚至兼任節
氣門控製和防護措施的部分、看門狗形同虛設的部分、無EDAC的部分、重要變量缺乏保
護的部分、使用了非標準化操作係統的部分,全部沒受到任何形式的反駁。


【第三部分】後記


寫到這裏,談談人們比較關心的幾點。當然還是外行眼光。
NASA / NHTSA怎麽沒發現這些問題?
NHTSA本身不具備檢驗電子係統的能力,於是委托NASA。NASA檢驗的是整個電控係統,
包括電控傳動部分,範圍比較寬,隻有很少一部分資源被用於檢驗軟件係統,也沒有投
入足夠的人力進行逐行代碼審閱。更何況在很多關鍵問題,比如之前提到的EDAC的使用
、堆棧的設計,NASA都直接采信豐田的回複,最終被證明不正確。甚至NASA從來都沒拿
到過監視芯片的源代碼,豐田的說法是“他們沒說要啊”。NASA報告雖然沒能找到軟件
係統導致暴衝的確切原因,但沒有否定其可能性。與之相比Barr的團隊全部都是嵌入式
係統專家,投入上千小時,深入程度甚至超過豐田自身對這個係統的理解(比如豐田沒
看過供應商的OS代碼,Barr看了)。
能否100%確定本案就是由軟件錯誤造成的?
不能。並沒有直接證據。訴訟團認為,軟件錯誤造成該事故的可能性比軟件錯誤沒造成
該事故的可能性大(原文:more likely than not)。
這裏再提一句,2005年款的凱美瑞沒有搭載行車數據記錄器(俗稱“黑盒子”),後來
的車款漸漸開始搭載。但是Barr發現這個記錄功能並不可靠,完全有可能記錄錯誤信息
。比如司機踩刹車了可能會被記錄成沒踩。
本案的意義
之前雖然豐田賠了不少錢,但是從未在涉及人身傷害的案件上承責。所以本案意義在於
開先例。美國的法律又特別注重先例,今後豐田的法務部門要頭疼了。
本案提到的有缺陷軟件涉及了哪些車型?
全部是美國的車型。Barr的調查重點是2005年款凱美瑞,另外審閱過的包括雷克薩斯ES
、Tacoma、卡羅拉和普銳斯等等,生產年份大致在2002年(電子油門元年)與2010年之
間。其中凱美瑞、雷克薩斯ES和Tacoma使用的軟件係統大致接近(原文:
Substantially similar)。另外根據統計,汽車暴衝投訴中與2004年款以後的凱美瑞
有關的案件數量激增400%。



最後的最後,放上本案關鍵證人Michael Barr的獨家訪談:


我:這麽看來似乎手動檔汽車更安全,你怎麽認為?
Barr:很多專家都這麽認為,離合器至少可以物理斷開動力係統。但是我翻閱卷宗,發
現其中有個案例是受害者開手動檔凱美瑞載著家人,突然巡航係統失靈,無法取消。他
踩下離合,同時試圖躲避前方慢速車輛結果失控衝出路麵造成單車事故。幸運的是沒死
人。


我:現在我們都知道豐田的軟件很糟糕。可是你對整個汽車行業的軟件水平有什麽看法
?豐田的軟件在同行內屬於什麽水平?
Barr:我沒有接觸過豐田以外的軟件代碼。但是請注意,這次發現的最嚴重問題是豐田
在設計源頭上沒有考慮安全,軟件質量反倒沒有那麽重要。隻要一個安全為先的設計,
比如刹車和關閉節氣門的可靠互動、防止節氣門開啟降低刹車效率的機製等等,不管軟
件有多差勁也不會造成致命結果。隻是我真不知道軟件還能怎麽差。


我:終極問題,你開什麽車?
Barr:我不開豐田。接觸該案以來我沒買過新車。老實說我現在非常害怕買新車。我倒
是問過一個與車企鬥爭了三十多年的職業狀棍同樣的問題,他開寶馬。

(注:事後有一台本田九萬邁,和一台豐田十六萬邁。伊乎牙哉。暴衝的尚未有。)
(注2: 其它車很難說要好到哪去,如果也能這樣看源碼。)

所有跟帖: 

有理有據。肯賠(沒有上訴)好幾百萬,外加私了的錢,車肯定是有毛病的。 -southmountainer- 給 southmountainer 發送悄悄話 (0 bytes) () 11/04/2013 postreply 20:39:37

Bar找出了根結,就這點豐田掏億元谘詢分析費也不算多 -日理萬機- 給 日理萬機 發送悄悄話 (16 bytes) () 11/04/2013 postreply 20:47:49

好文。越有曆史的車,軟件維護起來就越難。通常隻能補釘摞釘,如果推倒重來 -coolwin- 給 coolwin 發送悄悄話 (194 bytes) () 11/04/2013 postreply 20:52:29

做大批量產品最怕的就是出貨後發現較大的問題,特別是耐用品,售後服務的成本太高。 -US_CAR.- 給 US_CAR. 發送悄悄話 (0 bytes) () 11/04/2013 postreply 21:00:00

大體不錯,細節難料 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (763 bytes) () 11/04/2013 postreply 20:53:04

一個大函數把大部分的活都幹了,這就是典型三哥編程風格。在多任務係統中 -coolwin- 給 coolwin 發送悄悄話 (162 bytes) () 11/04/2013 postreply 21:02:12

什麽叫硬時鍾喂狗? -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/04/2013 postreply 21:05:28

文中“硬件時鍾中斷喂狗”的簡稱。除非鍾頻發生器壞了,否則這個中斷就一直產生。 -coolwin- 給 coolwin 發送悄悄話 (50 bytes) () 11/04/2013 postreply 21:11:33

你們說的全是外行話。 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/04/2013 postreply 23:22:15

是外行話。硬件時鍾如何喂狗? -企鵝肥肥- 給 企鵝肥肥 發送悄悄話 企鵝肥肥 的博客首頁 (0 bytes) () 11/05/2013 postreply 15:10:30

在硬時鍾中斷服務程序內將watchdog 計數器複位。 -coolwin- 給 coolwin 發送悄悄話 (18 bytes) () 11/05/2013 postreply 18:33:51

那按你的看法應該在那裏複位?中文作者原本就理解錯誤。 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 19:03:16

關鍵進程。一個千百萬都不能掛起的TASK,一但掛了,則馬上複位CPU。 -coolwin- 給 coolwin 發送悄悄話 (0 bytes) () 11/05/2013 postreply 19:10:35

"馬上"是多少1us,1ms還是1秒?你知道豐田是多少秒? -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 19:59:22

這樣說吧。你正常插入到拔出的時間是12秒。如果哪天你太太發現你進去了時間半天 -coolwin- 給 coolwin 發送悄悄話 (217 bytes) () 11/06/2013 postreply 00:46:43

中文作者一點都沒有理解錯。隻是這裏有人要攪渾水。 -coolwin- 給 coolwin 發送悄悄話 (0 bytes) () 11/05/2013 postreply 19:17:02

”一個大函數把大部分的活都幹了“-這未必是事實 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (599 bytes) () 11/04/2013 postreply 22:16:22

看來豐田該請你這免費大牛,讓Barr隻有襯托你的份, lol -日理萬機- 給 日理萬機 發送悄悄話 (0 bytes) () 11/05/2013 postreply 04:43:07

至少Barr是不夠高工資格的,美國的高手有的是 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 18:56:16

一個控製軟件竟然有1萬多全局變量,初中生也不是這個水平 -日理萬機- 給 日理萬機 發送悄悄話 (81 bytes) () 11/04/2013 postreply 20:59:57

滿身都是補釘(patch),想不出問題都難。 -US_CAR.- 給 US_CAR. 發送悄悄話 (0 bytes) () 11/04/2013 postreply 21:03:30

一萬多變量看你怎麽理解了,可能就是100KB內存吧? -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/04/2013 postreply 21:08:03

哈哈,你的程序課老師也是3哥?先不說全局變量的作用和副作用 -日理萬機- 給 日理萬機 發送悄悄話 (38 bytes) () 11/04/2013 postreply 21:25:52

以你的水平說說為啥它不用局部變量?你寫過嵌入式代碼嗎? -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/04/2013 postreply 22:51:38

為啥?當時便宜,符合豐田能省就省的風格。這篇供你學習 -日理萬機- 給 日理萬機 發送悄悄話 (292 bytes) () 11/05/2013 postreply 04:32:08

這個回答不對,再問一句為啥便宜? -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 07:36:28

這個都不知道,看來你的老師真是3哥了 -日理萬機- 給 日理萬機 發送悄悄話 (20 bytes) () 11/05/2013 postreply 15:18:43

你的意思是一罐可樂放在廳裏比放在廚房便宜 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 18:52:50

參數傳遞時,用全局變量非常容易。否則要壓棧再彈出,速度慢,還占堆棧。如果有遞歸 -coolwin- 給 coolwin 發送悄悄話 (240 bytes) () 11/05/2013 postreply 19:06:16

不是一萬多變量,是一萬多"全局"變量。 -US_CAR.- 給 US_CAR. 發送悄悄話 (0 bytes) () 11/04/2013 postreply 23:48:59

對就是10K,風格不好,但不是bug,MIPS專門有個全局變量尋址reg可訪64K -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 19:09:13

過分依賴電子控製的結果。 -隨風而來- 給 隨風而來 發送悄悄話 隨風而來 的博客首頁 (245 bytes) () 11/04/2013 postreply 21:30:53

國內原文題目:【年度巨獻】從外行的視角嚐試講解為什麽這回豐田栽了 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/04/2013 postreply 23:30:58

國人裏免費日車托很多,無非是維護自己開日車的麵子 -日理萬機- 給 日理萬機 發送悄悄話 (41 bytes) () 11/05/2013 postreply 05:16:28

再說一遍,控方/專家團沒能力找出事故的直接原因,國內評論也是外行寫的 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (6 bytes) () 11/05/2013 postreply 07:47:04

控方隻需要找出不是操作失誤即可,具體是那段程序出錯或哪個機構失靈等是廠家的功課。 -US_CAR.- 給 US_CAR. 發送悄悄話 (153 bytes) () 11/05/2013 postreply 08:11:16

“不是操作失誤”不需要找,控方也沒找出來。也沒人認為警察喪命是操作失誤 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (21 bytes) () 11/05/2013 postreply 11:28:33

控方沒有義務提供每一微小細節,足夠做出判斷就行 -日理萬機- 給 日理萬機 發送悄悄話 (0 bytes) () 11/05/2013 postreply 15:15:09

本貼的爭議並非在於控方該如何做 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (0 bytes) () 11/05/2013 postreply 18:57:46

Good to know汽車行業軟件有規範。汽車行業也應該enforce車用軟件 -N.- 給 N. 發送悄悄話 N. 的博客首頁 (169 bytes) () 11/05/2013 postreply 10:51:14

又是個誤解,那隻是個API的規範,雖然好過沒有 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (217 bytes) () 11/05/2013 postreply 11:34:34

你這個也是誤解,MISRA是為了安全/可靠性寫的規範/guideline,不是為了什麽API。 -N.- 給 N. 發送悄悄話 N. 的博客首頁 (107 bytes) () 11/05/2013 postreply 11:51:39

你的鏈接連API都不是,隻是標準C語言的一個子集 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (107 bytes) () 11/05/2013 postreply 16:11:56

MISRA還沒上道,看看都是誰吧: -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (373 bytes) () 11/05/2013 postreply 16:19:42

繼續攪渾-轉國內碼工的評論 -chinomango- 給 chinomango 發送悄悄話 chinomango 的博客首頁 (1244 bytes) () 11/05/2013 postreply 20:18:52

請您先登陸,再發跟帖!

發現Adblock插件

如要繼續瀏覽
請支持本站 請務必在本站關閉/移除任何Adblock

關閉Adblock後 請點擊

請參考如何關閉Adblock/Adblock plus

安裝Adblock plus用戶請點擊瀏覽器圖標
選擇“Disable on www.wenxuecity.com”

安裝Adblock用戶請點擊圖標
選擇“don't run on pages on this domain”