在2013年十月尾俄克拉荷马的一次庭审,2007年一辆2005年凯美瑞暴冲(UnintendedAcceleration,UA)致一死一伤变乱中丰田被判有责。引起广泛关注的是庭审中重要证人MichaelBarr的证词让陪审团同意丰田的动力体系软件存在巨大弊端大概导致此类变乱。这是丰田在同类变乱中第一次被判有责。庭审过后丰田立刻同意付出300万美元进入调解程序。
出于好奇,我不以为意地下载了Barr的286页证词,却一下子被吸引住了。几天内读完,算是对这次变乱举行了一次深入相识。下面就从生手角度总结一下这份证词并实行以更简单的语言表明内里提到的暴冲缘故起因以及丰田犯下的错误。
MichaelBarr是谁?他是一位拥有20年以上行业履历的嵌入式体系工程师。在十八个月中,有12位嵌入式体系专家,包Barr,受原告诉讼团所托,被关在马里兰州一间高度保安的房间内对丰田动力控制体系软件(重要是2005年的凯美瑞)源代码举行深度检察。
这房间没有英特网,没有手机信号,他们收支不能携带任何纸张、记录乃至皮带。末了的观察结果被写入一份800页,13章的具体陈诉。而鉴于保密协议,观察内容不停没有公布,直至俄克拉荷马这次庭审才首度部分公开(陈诉本身好像还没公开)。
回到正题。丰田的软件有没有缺陷?根据Barr的观察,答案是有。这着实是废话,任何软件都会有缺陷,关键在于是什么样的缺陷。丰田的软件缺陷分为三类:
非常业余的布局计划
软件计划的根本要求是模块只管简单化,由于如许可以一来更易于阅读二来更易于维护。但丰田的工程师显然没有依照这原则。Barr利用一种工具主动根据代码的大概分支数量评估函数的复杂度,结果是丰田的软件中至少有67条函数复杂度高出50,意味着运行这个函数大概出现高出50种差别的实行结果,属于“非可测”级别。由于为了测试这50个差别的结果,必须预备至少50条差别的测试用例以及相应的文档,在生产环境中一样平常是不实际的。作为比力,Barr表现他本身的公司严格实行的此中一条规定就是任何代码复杂度不能高出30,否则不合格。而在这67条函数中尚有12条复杂度高出100,到达“非可维护”级别,意味着一旦发现缺陷(Bug)也无法修复,由于着实太复杂,修复缺陷的过程中会产生新的缺陷。此中最复杂的一条函数有高出1300行代码,146个大概实行路径——恰好用于根据各传感器数值盘算节气门开关角度。
假如你不知道什么是节气门,那么这里我轻微表明一下。为了让内燃机运行,有三大要素:燃油、氛围和点火机遇。氛围和燃油的肴杂物进入气缸,被火花塞在精确的时间点燃推动活塞并终极推动曲轴和车轮进步。在电喷技能发明以后直到2002年从前,三大要素的燃油和点火时间是由电子装备控制,节气门机器毗连加快踏板,由司机直接控制。
节气门大抵是一个毗连加快踏板的“氛围龙头”——踩下去越多,“龙头”打开得越大,答应越多的氛围进入发动机输出更大的动力。2002年以后,丰田引入的“电子油门”让电子体系掌管了末了一个要素:氛围。加快踏板不再机器毗连节气门,而是毗连一些传感器,由行车电脑将这些传感器数值盘算成节气门开启角度再由马达控制节气门。我们稍后会再讨论节气门开合。
极复杂的代码带来的是极复杂的功能。下面说一下被称为“厨房洗涤盆”的TaskX。这里先表明一下,丰田的软件体系和很多别的软件系同一样,都是由一个统领程序(称之为“操纵体系”)和多少小程序(称之为Task)构成。就比如电脑上跑的Windows是统领全局的操纵体系,网络欣赏器和记事本是跑在操纵体系上的小程序。丰田的体系里每个Task都有本身的名字,但这些名字非常敏感,敏感到每次被提及的时间状师都要求法庭内的没有阅读代码权限的人全部清场。为了镌汰清场次数,Barr将这个最紧张的小程序称为TaskX。这个TaskX有多紧张呢?跟厨房里的洗涤盆一样紧张。它负责非常多的事变,包罗盘算节气门开启角度、速率监测和保持、定速巡航监测等等。TaskX的不正常运行被以为是暴冲变乱的首恶。稍后会再继承讨论TaskX。
尚有一些别的匪夷所思的发现。比如丰田的软件包罗了高出一万一千个全局变量。假如你不知道什么是全局变量,那么只必要知道软件计划的一样平常原则是要只管少利用全局变量,由于有大概带来无法猜测的结果。这里的“少”的意思是“只管靠近零”,绝对不会是一万一千个。
不符合软件开辟规范
如同很多行业一样,汽车行业也有本身的规范。更具体一点,由于汽车的伤害性子,汽车控制体系被分别为“安全关键性体系(SafetyCriticalSystem)”——说白了就是安全性非常紧张,弄不好会死人的。为了到达这一特别要求,汽车相干软件开辟职员定期举行集会会议讨论并发布编程规范,称为MISRAC。该规范的2004年版的感谢列表里还能看到丰田员工的名字,至少让外界以为丰田确实也在依照这些规范。
真的吗?根据源代码来看,答案是否定的。对此之前的NASA陈诉也有所提及,丰田辩称他们依照的不是行业规范,而是丰田内部编程规范。这一规范与行业规范的符合程度到达50%。但是Barr以为根据他的观察,两个规范之间符合度小于10%,乃至有多少规范条目相互辩论。厥后发现丰田的代码乃至没有依照丰田内部规范,固然比起别的题目这个已经无关紧急了。
MISRAC拥有高出100条规范,NASA的观察只利用了到此中35条举行校对,发现高出7000处违规代码。Barr利用全部条目,对照结果是丰田的程序拥有高出80000处违规代码。这些数字阐明白什么?根据统计,违规数量可以用于猜测代码中暗藏的缺陷(Bug)数量。在之条件到的汽车相干软件开辟职员集会会议中,有人就这一主题发表过专题演讲,提出每30处违规代码大概包罗一个庞大缺陷和十个轻微缺陷。讽刺的是这人是丰田员工。
特别必要指出MISRAC此中一个规则的内容是不得利用递归。
假如你不知道什么是递归,那么这里我轻微表明一下。递归是一种盘算方法。但一样平常盘算方法要么是本身算,要么扣问别的盘算模块索要结果。而递归则是通干涉一层层问本身的方法完成盘算。长处是代码简单,弊端是盘算层数不固定。大概会2层就出结果了,也大概会是10000层,在计划程序的时间无从得知。
软件盘算必要斲丧存储器。越繁琐、越长的盘算天然必要占用越多的存储器。递归的题目在于其嵌套层数无法猜测,从而导致大概斲丧的存储器容量无法控制。稍后会再讨论存储器。
对关键变量缺乏掩护
什么是变量?变量就是存在一段存储器的0和1的聚集。这些变量既可以是一些函数的处理惩罚结果,也可以是另一些函数的处理惩罚原质料。比方说前面提到有一条程序专门盘算节气门开合角度,比如说是20度,这个20就是一个变量,存在存储器的一个指定位置。另一个程序专门负责开合节气门,它知道去谁人指定位置读取这个20,然后把节气门开启20度。
什么是掩护?嵌入式体系,大概任何体系,都会在肯定条件下发生硬件大概软件错误。
客观上这是无法克制的。而且汽车作为一个时常在震动、发热、位移的体系,它的内部环境不能说不恶劣,发生硬件错误的大概性乃至更高。什么样的硬件错误呢?别忘了变量都是0和1的组合,这些0和1由存储器上的高低电平代表。由于某些不可抗缘故起因,一个电平从高变成低,大概反过来,那么这个变量就被更改了。这被称为“位反转(BitFlip)”。为了对抗如许的事变发生,必要对变量举行掩护。掩护的方法一样平常是镜像法。简单来说就是在两个差别的地方写入同一个变量,读取的时间两边都读,比力是不是同等。假如不同等,那么可以得知这个变量已经不可靠,必要举行容错处理惩罚。
丰田的程序总体上对其上万个变量举行了有效掩护,但题目出在操纵体系上。前面提到丰田的软件本质上分为操纵体系和Task。Task是由丰田本身开辟,但是操纵体系则是由芯片供应商提供,固化在芯片里的。丰田在这里的不对是没有对供应商提供的代码举行深度考核,拿到什么用什么。
另一个掩护步伐是错误校验码(ErrorDetectiveandCorrectionCodes,EDAC)。这是一个硬件层面的数据掩护步伐。简而言之就是给内存中每一个字节(8比特)背面物理地增长几比特校验码。如许万一变量堕落了,可以通过校验码得知,乃至可以通过校验码修复一些轻微错误。这个步伐非常简单有效,但是在2005年款凯美瑞的体系中完全没有利用,丰田却告诉NASA他们用了。而在2008年款凯美瑞中利用了3比专长的EDAC。
Barr以为是为了节流本钱,否则应该利用5比专长。
尚有值得一提的是,汽车相干的软件行业有那么几家操纵体系供应商,早已形成了一套成熟标准称为OSEK。各供应商开辟的符合OSEK认证的操纵体系至少都能到达肯定的质量。但丰田选用的操纵体系却没有通过认证,让人不解。
如今我们知道丰田在编写软件的时间至少有三种缺陷。那么重点题目:丰田的这些软件缺陷是否会导致车辆暴冲?根据Barr的观察,答案是有大概。暴冲的因由必要连合上述三种缺陷来阐明。
汽车正常运行必要倚靠多少程序(这里叫Task)的同时运作。Task有很多,CPU只有一块,在任何时候只能处理惩罚一个Task,怎么办呢?这必要操纵体系的统筹规划,公道分配CPU的任务,让每个Task都能按时实行。假如出现某种不测,让某个Task忽然不实行了,那么就称为这个Task“殒命”。Task死了,天然不能实行它的任务。根据Barr的测试,在某些特定环境下,TaskX的殒命可以导致节气门敞开——由于TaskX的此中一个任务就是根据司机的操纵盘算节气门开合角度,它死了也就没法重新盘算这个角度,纵然司机把脚挪开加快踏板,节气门也无法关闭。此为暴冲的直接缘故起因。更糟糕的是,节气门的开合角度这个数值,被TaskX算出来以后生存在一个变量中。这个特定的变量恰好没有被掩护(缺陷3)。意味着万一TaskX殒命而且克制盘算,这个数值有大概由于不可抗缘故起因被改变,而程序无从得知。
那么TaskX为何会殒命呢?一样平常是由于内存堕落。这个堕落大概是一个小小的位反转,也大概是内存里的数值被别的程序错误覆盖。同一体系内同时运行了多少程序,这些程序必要共享一块内存,内存内部肯定要被分别成多少块。比如第一块给程序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年的凯美瑞的这部分供应商是电装,没有搭载堆栈及时监测功能——溢出了也不知道。同年的卡罗拉却搭载了,由于供应商是通用。
到这里我小结一下:
堆栈溢出→(大概导致)→任务分配表被改写→(大概导致)→TaskX殒命→(大概导致)→节气门敞开→(导致)→汽车暴冲
必须指出的是,这条链子从最左边不停到TaskX殒命,都还算是嵌入式体系的常见故障。固然程序代码写得不好大概导致更轻易堕落,客观上丰田并没有特别大的不对。只要处理惩罚得当,这些故障都不会导致暴冲。
到此为止还只是前奏而已,接下来我们来看看丰田到底做错了什么。
丰田之罪
上面反复提到,嵌入式体系中内存堕落大概程序殒命着实是一种正常征象——至少从Barr的证词可以得出这个结论——如今连我们都知道了,嵌入式工程师肯定比我们更清楚才对。确实,为了使体系正常运行不被错误干扰,一样平常的做法是设置多少层防护步伐(Failsafe),让运行中出现的错误无法轻易突破,得到妥善处理惩罚。丰田的工程师天然也懂得这一点。很痛惜,他们搞砸了。
上面那条链子应该修改成如许:
(防护步伐0)→堆栈溢出→(防护步伐1)→(大概导致)→任务分配表被改写→(防护步伐2)→(大概导致)→TaskX殒命→(防护步伐3)→(大概导致)→节气门敞开→(防护步伐4)→(导致)→汽车暴冲
可以看到,防护步伐不可谓不多。只要处理惩罚得当,这链条应该是走不通的。如今让我们从左到右看一个小小的内存错误是怎样一层层突破防护终极导致汽车暴冲的。
起首防护步伐0。这个着实上面提到了,由于计划缺陷低估了最大占用的存储容量,而且不符合规范地利用了递归,终极大概导致堆栈溢出。
然后到防护步伐1。上面也提到了,任务分配表紧邻堆栈。作为生手我都以为这是个非常伤害的计划——既然堆栈这么轻易溢出,好歹应该将任务分配表放远一点啊。固然我是生手,大概实际上比想象中复杂很多。这段Barr的证词中并未特别提到,属于我的个人明白。
防护步伐2。从这里开始丰田的错误越发严峻。任务表被改写导致某些Task运行非常,在软件层应该有多少检测步伐,比方说用特别的监督Task来监督别的Task是否正常。但丰田是怎么做的呢?还记得上面的“厨房洗涤盆”TaskX吗?它是云云复杂(缺陷1),除了控制汽车运行的任务之外竟然还兼任大部分的监督任务,比如天生DTC。
DTC(diagnostictroublecodes),是汽车电脑体系会根据环境天生的错误代码。有的车主大概会碰到汽车某报警灯常亮,修车师傅拿个仪器插在行车电脑上得出一个代码,再查表就知道哪个元件坏了——这就是DTC。除了用于修车,DTC还被用于检测行车电脑和各传感器的非常状态。
可以想象,这个既是活动员又是裁判的TaskX一旦殒命,软件层的检测步伐大部分就失效了。
防护步伐3。在这里丰田的错误开始到达顶峰。纵然设置精确无误,上面提到的监督Task也只不外是另一个Task而已,与它的监督对象算是平级——监督Task本身同样有大概出现故障。嵌入式体系的一样平常做法是在全部程序之上再设置一道屏蔽,被称为“看门狗(Watchdog)”。所谓看门狗,是一个优先级很高的倒计时程序。别的程序必要在运行的时间特意去重置一下这个计时器让它重新开始倒计时,这个动作被称为“喂狗”。
假如由于程序出题目太长时间不喂狗,倒计时完成,看门狗知道什么地方卡住了,立刻采取步伐,比如重启整个体系。重启体系听起来好像很严峻,实际上却是一件相称平凡的事变。嵌入式体系的重启非常快,时速100公里的汽车中动力体系可以在半米之内完成重启——车上的人根本觉察不到。
通过阅读代码和拟真实行,Barr惊奇地发现上述嵌入式体系的知识性做法竟然在丰田软件体系内不存在!丰田的软件确实有一只看门狗,但它竟然不是用于监督Task非常,而是用于防止CPU过载。起首这个做法不能说后无来者至少算是前无古人。还记得上面提到的800页13章的陈诉吗?理屈词穷的Barr将丰田看门狗的分析结果写入了陈诉的第一章,由于他着实太震动。其次,丰田看门狗的防止CPU过载功能也相称蹩脚,在拟真测试发现纵然它正常工作,还是会答应CPU过载时间长达1.5秒——时速100公里的车能跑40米以上。CPU一旦过载,就会导致全部的Task进入一种“假死”状态,无法处理惩罚信息,这时司机无法控制汽车动力,非常伤害别的,丰田的工程师还犯了一个嵌入式讲堂上被反复提到的经典错误:利用硬件时钟停止喂狗。硬件停止拥有非常高的优先级,纵然Task卡住(比如出现死循环)也不能制止硬件停止——可想而知如许一来看门狗就便是完全白瞎了。
这里也提一句,同年的普锐斯却令人不测地搭载了一只运作正常的看门狗,反而让人摸不着头脑。
还没完。这一层防护是嵌入式体系的关键阵地。前面都是电子体系,背面立刻进入机器运作,足以造成劫难了。以是仅仅拥有软件级别的防护还不敷够,丰田的做法是在主CPU之外单独设置了一块监督芯片,从硬件级别对体系的运作举行监督。监督芯片有两个任务。第一,它运行一种叫做体系卫士(SystemGuard)的程序,原理上来说是专门用于防止暴冲。主CPU和监督芯片上都会运行体系卫士,但是研究发现TaskX一旦殒命,这些体系卫士齐备都不起作用了。第二,它运行一个被称为“刹车回声查抄(BrakeEchoCheck)”的程序。这个程序从代码上来看好像可以检测出TaskX的殒命,而且采取相应步伐:关闭节气门。听起来像是好消息,但是同样有题目:起首这个程序不太可靠,纵然正常运行,理论上也有失效的大概。最关键的是该程序不会主动运行,必要司机先对刹车踏板有“动作”才会触发。留意这里我特意没用“踩刹车”这个词,由于根据分析“触发动作”非常令人狐疑。它分两种环境:假如TaskX殒命的那一刻司机的脚不在刹车踏板上,那么触发动作是踩刹车。还算可以明白。另一种环境,假如TaskX殒命那一刻司机的脚踩在刹车踏板上,那么触发动作是完全开释刹车踏板。没错,察觉车子在不正常加快的司机必要克制踩刹车才华让控制体系关闭节气门!这种违背人类认知的举动应该不是丰田工程师特意计划的。假如是,他们到底在想什么啊?
到此为止,上面提到的都算是“战术层面”的错误,都是“小错”。在讲授这块监督芯片的时间,可以发现丰田犯下最严峻的“战略层面”错误——底子计划。Barr以为,假如底子计划精确,上述那些小错都完全不会导致汽车暴冲——不管代码写得多业余,不管内存错误多严峻,不管Task死得多频仍,齐备不会致命。让我们回到2002年从前,没有电子油门的时间。当时候的拉线油门是由油门踏板机器毗连的。当驾驶员的右脚踩下刹车,他的右脚肯定不在油门踏板上,节气门天然而然地被关闭。这个动作云云天然,乃至算不上安全步伐,仅仅由于每人只有一只右脚,不大概同时踩油门和刹车。当丰田计划电子油门的时间,只要轻微有点知识,都应该从计划阶段就将这一“天然而然”发生的动作思量进去。但是很显然,他们没这么做。监督芯片上运行的代码是用汇编语言(一种更加靠近呆板实行代码,阔别人类语言,更加难懂的编程语言)编写的,运行条理比主CPU的C语言更低。Barr以为假如计划得当,现有的监督芯片完全有本领胜任上述功能,必要的仅仅是几百行代码,别的什么都不消更改——不会进步任何生产本钱。很遗憾,他们没有做到。
防护步伐4。如今已经离开电子体系,节气门已经敞开,发动机全速运转,必要利用机器运作来构造机器运作了。怎样让向前冲的车子停下来?不开车的人都知道,刹车!当代汽车都装备了刹车助力,助力来自于发动机运转的时间产生的负压。我们知道发动机必要吸入氛围,吸入体积便是排宇量乘以转速。节气门又是用来拦截氛围的,那么节气门关闭而发动机转速相对高的时间(比如高速丢油门),发动机的实际氛围吸入量比它能吸入的体积要少,那么从节气门到气缸进气口之间会形成显着低气压(所谓负压,比大气压力小)。刹车助力就是利用了这个负压推动气鼓产生更大的推力动员刹车片抓紧刹车盘。但是假如节气门敞开让氛围任意进来,低气压就不存在了,这时刹车助力大大减弱,刹车服从也大大低落。这就是为什么暴冲变乱当事人都说全油门的时间根本刹不住的紧张缘故起因。这个征象称为“真空丧失(VacuumLoss)”,存在于全部天然吸气的汽油发动机汽车(柴油和增压发动机没影响),不算丰田的错。但丰田迟迟不搭载刹车优先体系(BrakeOverrideSystem)答应刹车的同时敞开节气门,毫无疑问是这个征象的帮凶。
所谓刹车优先体系,指的是包管同时踩下刹车油门两个踏板的时间无条件关闭节气门的功能。这么做很显然重要是为了低落发动机输出,同时也包管刹车助力。丰田在2010年的凯美瑞上终于搭载了刹车优先体系,但是别高兴得太早。根据Barr的观察,丰田竟然将云云紧张的修改“理所固然”地写入了他们的“厨房洗涤盆”——TaskX。我只能“哑然失笑,扼腕叹息”。
好了,到此为止都还是Barr的一面之词,而且大部分都是在那间保卫森严的房间内举行拟真测试得出的“理论结果”。那么实车测试环境怎样呢?丰田对Barr的证词怎样反驳呢?
先说说实车测试。为了证明理论,他们把2008年和2005年的凯美瑞放在马力机上,固定车身架起前轮模仿车辆运行环境。他们的做法是起首让车子运行在时速68英里(110公里),启动巡航,脚离开油门踏板。然后停息巡航,速率开始降落。降落到肯定程度规复巡航,速率开始上升。在到达68英里的设定时速从前,他们用一台毗连行车电脑的条记本“注入”错误。所谓注入错误,就是人为地翻转一个特定字节——将0改成1,大概反过来——模仿内存破坏。结果完全符公道论,时速高出68英里也不绝止加快,直至时速90英里(145公里),测试职员踩下刹车。约莫1秒以后节气门被关闭,Barr以为这是上述“刹车回声查抄”的功劳。
实车测试证明白Barr的理论,却并不是全无漏洞。丰田辩护状师就两点提出质疑:
实车测试利用人工注入错误的方法,并不能证明实际中这种错误就肯定会发生。
对此Barr的答复是测试的范围性。由于测试时间、样本有限,而待测试的样本空间无穷大。假如要等待谁人特定的错误天然出现,大概必要成百万上亿小时的不停止测试,显然是不实际的。更何况从科学上而言,没有办法对这个错误证伪——就比如无法证明宇宙里没有外星人,最多只能证明火星上找不到而已。但是这个测试足以证明一个小小的位翻转确实可以突破重重停滞终极导致暴冲,足以证明丰田的软件存在不能容忍的隐患。
Bookout密斯(本案原告)声称,在她驾驶汽车离开高速的时间发现不受控加快,她冒死反复踩下刹车而且拉起手刹,现场留下了刹车陈迹。但并没有迹象表明发动机动力停止——换言之“刹车回声检测”没起作用。暗指Barr的理论站不住。
对此Barr的答复是起首只管在实车测试中每次都见效,但代码分析表明“刹车回声查抄”这一功能在理论上靠不住。其次这一功能的别的一个触发动作是要让脚完完全全离开刹车踏板。试想车子正在不受控地往前冲,任何人都会不由自主地踩刹车,让人完全不踩刹车踏板根本就是违背认知的。Bookout密斯纵然如同她所称反复踩刹车,很大概只是不停将脚放在踏板上往复活动,从未完全挪开。Barr还引用一位丰田本身的软件专家的证词。该专家承认,假如发生暴冲的时候脚恰好打仗到刹车踏板,而且之后不停没挪开,那么汽车的暴冲间隔“取决于还剩多少汽油”。
末了顺带说一下那份800页,13章的具体陈诉完成后,Barr将其提交给了丰田的软件部分,等待他们的反驳。最闭幕果是“非常少(Verylittle)”,13章中的11章,包罗堆栈溢出的部分、代码紊乱的部分、违背开辟规范的部分、TaskX过于痴肥乃至兼任节气门控制和防护步伐的部分、看门狗形同虚设的部分、无EDAC的部分、紧张变量缺乏掩护的部分、利用了非标准化操纵体系的部分,全部没受到任何情势的反驳。
特别保举
我要评论