虽然工作在最近的一个项目,我访问了一个客户QA代表,他问我一个问题,我真的没有审议之前:

你怎么知道那个编译器,你正在使用产生的机器码相匹配的c码的功能的完全和编译器完全确定?

这个问题我绝对没有答复,因为我一直采取的编译为当然。它需要在码和喷出的机器码。怎么我可以去约和测试,编译器并不是实际上添加功能,我还没问呢?甚至更危险的实施代码在一个稍微不同的方式,我期待什么呢?

我知道,这是perhapse不是一个真正的问题,对于每个人,实际上答案可能只是..."你超过每桶和处理它"。然而,当工作中嵌入式的环境中,你相信你的编译器隐含.我怎么能证明自己和质量保证,我正在这么做?

有帮助吗?

解决方案

对安全的关键嵌入式应用程序认证机构需要满足"证明在使用"的要求编译器。通常有一定的要求(一种像"小时运作"),需要得到满足,并证明通过详细的文件。然而,大多数人不能或不想要满足这些要求,因为它可能是非常困难尤其是您的第一个项目与新的目标/编译器。

一个其他的方法是基本上不相信编译器的输出。任何编译器,甚至依赖于语言(附录G C-90的标准,任何人吗?) 不足,需要由一套严格的静态分析,单位和测试的复盖范围以外后来的功能测试。

标准样 MISRA-C 可以帮助限制输入的编译器,以一个"安全"的子集C语言。另一个办法是限制输入到一个编译器的一个子集的语言和测试什么的输出,用于整个子集。如果我们的应用是唯一内置的组件,从子也被假定为已知什么样的产出的编译器会。这通常通过"资格的编译程序".

我们的目标的所有这一切都是能够回答的QA代表的问题与"我们不要只是依赖确定性的编译器,但这是我们的方式证明它...".

其他提示

你可以申请这一论点,在任何等级:你信任的第三方的库?你信任的操作系统?你相信处理器?

一个很好的例子为什么这可能是一个有效的担忧当然是,如何肯*汤普森把后门进入原始的"登录"的节目...和修改C编译器,以便即使你重新编译登录你还有后门。看看这个 发布 更多的细节。

类似的问题已经提出了关于加密算法--我们怎么知道有没有后门DES为国家安全局为窥探过去吗?

在结束你必须决定如果你信任的基础设施正在建设的足够不用担心,否则的话你必须开始发展自己的硅芯片!

你知道的测试。当你的测试,你的测试你的代码和编译器。

你会发现,赔率是你或编译器的作家作出了一个错误,小得多的比率,你将成为一个错误,如果你写的问题的程序在一些组件的语言。

有编译器验证服。
我记得是 "多年生".

当我工作上有C编译器,用于一个嵌入式SOC处理我们必须验证编译器反对这个和两个其他的验证服(我忘记了名字)。验证编译器一定程度的一致性对这些测试的诉讼是合同的一部分。

这一切都归结到信任。没有你的客户信任的任何编译器吗?使用,或者至少比较输代码之间你和他们的。

如果他们不信任,是有一个参考执行的语言?你能说服他们相信它吗?那么你比较对基准或使用的参考。

这所有的假设你实际上验证的实际代码你得到从供应商/供应商和检查的编译器没有被篡改,这应该是第一步。

无论如何,这仍然留下的问题,关于你会如何核实,而不必参考文献,一个编译器,从头开始。这肯定看起来像一吨的工作和需要的定义的语言,它不是总是可用的,有时定义是编译器。

你怎么知道那个编译器,你正在使用产生的机器码相匹配的c码的功能的完全和编译器完全确定?

你没,这就是为什么你的测试所得到的二进制的,并为什么你一定要船舶相同的二进制你的测试。为什么当你做'小'软件变化,则回归测试,以确保没有古老的功能打破。

唯一的软件,我们认为航空电子设备。联邦航空局证不严格足以证明软件的正常工作,而同时不会强迫你跳过一定数额的篮球。诀窍是结构你的'过程',所以它提高了质量尽可能与作为多余的小圈-跳为你可以逃脱。所以任何东西,你知道是毫无价值和实际上不会发现错误,你也许可以黄鼠狼。什么你知道你应该做的,因为它 发现错误,不是有明确要求通过联邦航空局你最好的赌注是扭转的话,直到它听起来就像你给美国联邦航空局/QA人什么他们提出的要求。

这实际上是不是不诚实的,因为我已经做了它的声音,一般的美国联邦航空局更关心你是认真的,相信你 试图 做一个好工作,超过什么你到底做。

一些知识产权弹药可能会发现在扰、一份杂志,用于防御的软件工程师。这个问题是什么样的事情他们花费许多小时清醒。 http://www.stsc.hill.af.mil/crosstalk/2006/08/index.html (如果我能找到我的老注意到,从一个旧的项目,我将回到这里...)

你永远不会完全可以信任的编译器,甚至是强烈建议的。他们可以释放更新,有一个错误,你的代码汇编相同。这一问题更加复杂当更新老码的车编译器,这样做测试和运输的货物只有客户环你3个月后有一个问题。

这一切又回到了测试,并且如果有一件事我学到就是thouroughly试验之后,任何重要变化。如果这个问题似乎不可能找到有一个看起来在编制的汇编,并检查它是做什么的,它应该做的。

在几个场合我们发现错误在编译器。一段时间有一个错误,16位变量将得到增加,但没有携带和只有16位变量的一部分的一个外部结构定义在一个标题的文件。

...你信任你的隐含地编译器

您将停止这样做你第一次遇到一个编译器的错误。;-)

但最终这是什么测试。不要紧以你的测试制度如何的错误得到你的产品在第一位,重要的是,它没有通过广泛的测试制度。

嗯..你不能简单地说你信任你的编译器的输出,特别是如果您使用嵌入的代码。这是不是很难找到差异的产生码当汇编非常相同的代码与不同的编译器。这种情况,因为C的标准本身过于宽松。许多详细信息可以以不同方式实现通过不同的编译器而不破坏的标准。我们如何处理这些东西?我们避免编译器的依赖结构只要有可能。我们可能处理它通过选择一个更安全的子集C喜欢 Misra-C 如前面所提到的用户cschol.我很少有来检查产生的代码编译器,但也发生在我身上的时候。但是,最终,你们依靠你的测试,以便以确保代码的行为为目的。

是有一个更好的选择吗?一些人认为是有的。其他的选择是要写你的代码中 火花/艾达.我从来没有写代码在火,但我的理解是,你仍然会有链接,它对程序C编写的,将处理的"裸露的金属"的东西。美丽的火花/Ada的是,你绝对保证代码生成的任何编译器,是永远都会是一样的。没有模糊的任何责任。最重要的是,语言可以让你代码注释解释了如何编码为目的的行为。火花工具将使用这些说明正式证明,编写的代码确实做什么的批注已经描述。因此,我已被告知,关键的系统,火花/艾达是一个很好的赌注。我从来没有尝试过自己。

你肯定不知道那个编译器会做的正是你所期望的。其原因是,当然, 编译是一个片的软件, ,因此容易受到错误。

编译器作家具有优势的工作,从一个高质量规格的,而其余的我们必须弄清楚什么我们在使我们走。然而,前编译器 有错误和复杂的部分微妙的相互作用。所以,它不是完全微不足道要找出什么的编译器应该做的。

仍然,一旦你决定你怎么想的语言规范的手段,就可以写好,快速、自动化测试的每一个细微的差别。这是在编译器的写作有巨大的优势,通过编写其他类型的软件:在测试。每一个错误成为一个自动化测试的情况下,测试可以非常透彻。编译器供应商有更多的预算,以投资于验证正确性的编译器比你所做的(你已经有一个白天的工作,对吗?).

这是什么意思你?这意味着你需要开放的可能性的错误在编译器,但是你不会找到任何你自己。

我会选一个编译器供应商是不可能走出去的企业的任何时间不久,这一历史的高质量在他们编译器,并具有证明自己有能力服务(补)他们的产品。编译器似乎得到更多的正随着时间的推移,所以我会选择一个已经十年或两个。

把你的注意力集中在获取你的代码权利。 如果它 清晰简单, 然后当你 打一个编译的错误,你会不会觉得真的很难决定哪里出了问题所在。 写好的单元测试, 这将确保你的代码有没有什么你期望它做的。

试图单元的测试。

如果这还不够,使用不同的编译器和比较的结果的单元测试。比较strace产出,运行测试在一个虚拟机,记录的磁盘和网络I/O,然后进行比较。

或建议编写自己的编译器,并告诉他们什么要费用。

最你可以很容易地证明是,你正在使用一个未被篡改编译器从供应商X.如果他们不信任的供应商,X,这是他们的问题(如果X是合理的可信赖的).如果他们不相信任何编译器供应商,然后他们是完全不合理的。

回答他们的问题:我要确保我使用一个未被篡改编译器X通过这些装置。X是知名的,再加上我有一个很好的测试,表明我们的应用程序的行为,如预期的那样。

其他一切开始打开可以的蠕虫。你必须停止的地方,作为Rob说。

有时候,你做得到行为改变的时候你的要求积极平的优化。

和优化和浮点的数字?忘了它!

对大多数软件的开发(认为桌面应用程序)的答案是可能的,你不知道和不关心。

在安全至关重要的系统(为核电厂和商业航空电子设备)你 护理和管理机构将需要证明这一点。以我的经验你可以这样做的两种方法之一:

  1. 使用一个合格的编译器,其中"资格"指的是它已经被验证根据规定的标准由管理机构。
  2. 执行目标代码分析。基本上,你汇编一块参考代码然后手动分析的产出表明,编译器具有不插入任何指示,不能追溯到你的源码。

你会得到一个Dijkstra写的。

选择一个正式验证编译器,就像Compcert C编译器。

  1. 改变优化水平将改变编译器的输出。
  2. 稍微改变一个功能可以使编译器内联或不再是联的功能。
  3. 改变编译器(海湾合作委员会的版本,例如)可能会改变的输出
  4. 某些图书馆的功能可以instrinic(即,优化这些组件),而其他人大多数都没有。

好消息是,对于大多数事情就真的不重要是很多。它不会,你可能要考虑大会如果真正的问题(例如,在一个ISR).

如果你感到关切意想不到的机的代码不会产生可见的结果,唯一的办法可能是联系编译器供应商为证明一些排序,这将满足你的顾客。

否则你就会知道它是一样的,你知道虫子在你的代码-测试。

机器码,从现代的编译器可以极大地不同的,完全不可理解为弱小的人类。

我认为这是可能减少这个问题的 停止问题 不知何故。

最明显的问题是,如果使用某种程序来分析编译器及其决定论你怎么知道 你的 程序得到汇编正确,并产生正确结果?

如果您使用的是另一个"安全"编译器,虽然,我不知道。什么我肯定是写一个编译器,从头开始可能是一个容易的工作。

甚至是一合格或核证的编译器可以产生所不希望的结果。保持你的代码的简单测试,测试,测试。这或步行通过机代码的方面,同时不允许任何人为错误。加操作系统或任何环境中运行(最好没有操作系统,只是你的节目)。

这个问题已经解决的关键任务环境,因为软件和编译器开始。作为许多其他人已经回答了还知道。每个产业都有其自己的规则从认证的编译器编程的风格(你必须一直计划这种方式,永远不会使用这个或那或其他),大量的检测和同侪审查。验证每一个执行路径,等等。

如果你不在这些行业,然后你得到你会得到什么。商业程序,在婴儿床上操作系统的婴儿床的硬件。它将失败,这是一个保证。

如果你担心 恶意 错误的编译器,一种建议(请参考,国家安全局的要求,对于某些项目)是二进制编译器之前编写的代码。至少你知道,没有人 加入 错误的目标 你的 程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top