为什么在空间/辐射环境中不建议使用C ++模板?


69

通过阅读此问题,例如,我理解了为什么不建议在空间或核电站等辐射较高的环境中进行动态分配或例外处理。关于模板,我不知道为什么。你能给我解释一下吗?

考虑到这个答案,它说使用起来很安全。

注意:我不是在谈论复杂的标准库内容,而是在专门定制模板。


12
我的猜测不是因为环境,而是因为在资源非常有限的嵌入式系统上运行程序。模板往往会产生“膨胀”,因为模板可能导致不同实例化的代码重复。
一些程序员花花公子

5
火星上有关C ++的关注点在Rover演示文稿的第34页上,与辐射无关。(我认为您所指的答案的下半部分与辐射
无关

9
最后,模板只是普通的类和函数。忽略其他原因,例如可能的代码膨胀或较长的编译时间,应该没有理由不使用它们。
一个人猴小队

21
它与辐射或代码大小无关。安全设计指南通常会尝试降低代码的复杂性(短函数,无间接调用,仅静态内存分配等)。这些指南中的许多是在LINT是您可以进行代码分析的最佳方法时编写的。因此,并非所有这些规则仍然有意义。
user6556709

10
理论上,您可以将C ++的受限子集用于此类系统。实际上,您避免像瘟疫一样避免C ++是因为它太复杂了,您永远不能相信C ++程序员坚持安全子集。在不知不觉中,整个程序中都有模板元编程地狱。此外,C ++ 11和更高版本的许多新功能(例如的行为auto)将使您大吃一惊。
隆丁

Answers:


113

请注意,与空间兼容的(辐射硬化的,符合航空航天标准的)计算设备非常昂贵(包括在太空中发射,因为它们的重量超过了千克),而且一次太空飞行可能要花费1亿欧元或美元。由于软件或计算机问题而失去任务通常要付出高昂的代价,因此这是无法接受的,并且证明了开发手机小程序根本不希望使用的昂贵的开发方法和过程,并且建议使用概率推理和工程方法,因为宇宙射线仍然是某种“异常”事件。从高级的角度来看,宇宙射线及其产生的位翻转可以视为某种抽象形式的信号或输入的噪声。您可以将“随机位翻转”问题视为信噪比问题,然后随机算法可以提供有用的概念框架(尤其是在元级别,即在分析安全关键源代码或编译时)。二进制,也可以在关键的系统运行时,在某些复杂的内核或线程调度程序中,以信息论的观点。

为什么不建议在空间/辐射环境中使用C ++模板?

该建议是一个概括,对C ++的MISRA C编码规则和嵌入式C ++的规则,以及DO178C建议,它是不相关的辐射,但到嵌入式系统。由于辐射和振动的限制,任何太空火箭计算机的嵌入式硬件都必须非常小(例如,出于经济和能源消耗的原因,与大型x86服务器系统相比,在计算机功能上,它更像Raspberry Pi) )。空间硬化芯片的成本是民用同类芯片的1000倍。在太空嵌入式计算机上计算WCET仍然是一项技术挑战(例如,由于CPU缓存)相关问题)。因此,在安全性要求很高的嵌入式软件密集型系统中,堆分配不受欢迎(您将如何处理其中的内存不足情况?或者如何证明您有足够的RAM用于所有实际运行时情况?)

请记住,在安全性至关重要的软件世界中,您不仅会以某种方式“保证”或“承诺”,而且肯定会(通常使用一些聪明的概率推理)评估您自己的软件的质量,而且还会评估用于进行构建(尤其是:您的编译器和链接器;未经FAADGAC的书面许可,波音公司或空中客车公司将不会更改其用于编译其飞行控制软件的GCC交叉编译器的版本)。您的大多数软件工具都需要以某种方式批准或认证。

请注意,实际上,大多数C ++(但不是全部)模板内部都使用堆。标准C ++容器当然可以。编写从未使用堆的模板是一项艰巨的任务。如果有能力,您可以安全地使用模板(假设您确实信任C ++编译器及其模板扩展机制,这是最新的C ++编译器(例如GCCClang)的C ++前端最棘手的部分)。

我想出于类似(工具集可靠性)的原因,使用许多源代码生成工具(进行某种元编程,例如发出C ++或C代码)并不受欢迎。注意,例如,如果你使用bison(或的rpcgen在一些安全关键软件)(由编译makegcc),您需要评估(也许详尽测试)不仅gccmake,而且还bison。这是工程原因,而不是科学原因。请注意,某些嵌入式系统可能会使用随机算法,特别是为了巧妙地处理噪声。输入信号(可能是由于稀有的宇宙射线而导致的甚至随机位翻转)。证明,测试或分析(或只是评估)此类基于随机的算法是一个非常困难的话题。

还查看Frama-ClangCompCert,并注意以下几点:

  • C ++ 11(或之后的版本)是一种极其复杂的编程语言。它没有完整的形式语义。在全球范围内,只有几十人具备C ++的专业知识(可能大多数人都在其标准委员会中)。我能够用C ++进行编码,但不能解释所有移动语义或C ++内存模型的微妙情况。另外,C ++实际上需要进行许多优化才能有效使用。

  • 制作无错误的C ++编译器非常困难,特别是因为C ++实际上需要棘手的优化,并且由于C ++规范的复杂性。但是当前的(例如最近的GCC或Clang)在实践中相当不错,并且它们几乎没有(但仍然有一些)残留的编译器错误。目前还没有针对C ++的CompCert ++,制作一部需要几百万欧元或美元(但如果您可以收取这么多的钱,请通过电子邮件与联系,例如basile.starynkevitch@cea.fr,发送至我的工作电子邮件)。太空软件行业极为保守。

  • 很难创建一个好的C或C ++堆内存分配器。编码是一个权衡的问题。开个玩笑,考虑使此C堆分配器适应C ++。

  • 事实证明,与模板相关的C ++代码的安全属性(特别是缺少竞争条件未定义的行为,例如运行时缓冲区溢出)在2019年第二季度仍比C ++代码的静态程序分析技术要先进一些。我的Bismon技术报告草稿(这是H2020交付的草稿,因此请跳过欧洲官僚的页面)有几页对此进行了更详细的说明。注意莱斯定理

  • 整个系统的C ++嵌入式软件测试可能需要发射火箭(la Ariane 5测试飞行501,或至少在实验室进行的复杂而繁重的实验)。这非常昂贵的。即使在地球上进行测试,火星探测器也需要大量资金。

想一想:您正在编写一些对安全性至关重要的嵌入式软件(例如,用于火车制动,自动驾驶汽车,自动驾驶无人机,大型石油平台或炼油厂,导弹等)。您天真地使用了一些C ++标准容器,例如some std::map<std::string,long>。内存不足情况该怎么办?您如何向资助1亿欧元太空火箭的组织中的人员“证明”或至少“说服”您的嵌入式软件(包括用于构建它的编译器)足够好?十年前的规则是禁止任何类型的动态堆分配。

我不是在谈论复杂的标准库,而是专门针对性的自定义模板。

甚至这些都很难证明,或更一般地说,很难评估它们的质量(您可能希望在其中使用自己的分配器)。在空间上,代码空间是一个强大的约束。因此,您可以使用g++ -Os -Wall或进行编译clang++ -Os -Wall。但是,您如何证明(或只是测试)通过的所有细微优化-Os(这些特定于您的GCC或Clang版本)?您的太空资助组织会问您,由于嵌入式C ++太空软件中的任何运行时错误都可能使任务崩溃(请再次阅读有关阿丽亚娜5首次飞行失败的信息-用Ada的某些方言编码,当时该词具有“更好的”比“今天的C ++ 17”更“安全”的类型系统),但不要对欧洲人笑得太多。带有其MACS的波音737 MAX类似情况)。


我个人的建议(但请不要太在意。在2019年,它比其他任何事情都更容易理解)将是考虑使用Rust编写您的太空嵌入式软件。因为它比C ++更安全。当然,您将需要在5到7年内花费5到1000万欧元(或MUS $),以获得适用于太空计算机的优质Rust编译器(同样,如果您有能力花费,请与我专业联系)免费软件Compcert / Rust之类的编译器)。但这只是软件工程和软件项目管理的问题(有关更多信息,请阅读《神话般的月刊》和《胡说八道》,也请注意迪尔伯特原理。:它适用于太空软件行业或嵌入式编译器行业,以及其他任何方面。

我的强烈个人观点是,欧盟委员会应资助(例如通过Horizo​​n Europe)类似项目的免费软件CompCert ++(或更好的是Compcert / Rust),而此类项目将需要5年以上且5次以上级博士研究人员)。但是,在60岁那年,我很遗憾地知道这将不会发生(因为EC意识形态-主要是出于明显的原因而受到德国政策的启发-仍然是“历史终结”的幻象,因此H2020和Horizo​​n Europe在实践中,主要是通过欧洲避税天堂为欧洲公司实施税收优化的方法,并且在与CompCert项目的几个成员进行了几次私下讨论之后。我很遗憾地期望DARPANASA更有可能资助某些未来的CompCert / Rust项目(比EC资助)。


注意 欧洲航空电子业(主要是空中客车公司)正在使用比北美航空(波音公司)更为正式的方法。因此一些(不是全部)被避免单元测试(因为替换形式证明的源代码,或许与像工具邮资-CASTREE -既不是已认证的C ++,只对一个子集的C禁止时的动态存储器分配和几个C的其他功能)。这是由DO-178C允许(而不是先前的DO-178B)并由法国监管机构DGAC批准(我猜是由其他欧洲监管机构批准)。

另请注意,许多SIGPLAN会议与OP的问题间接相关。


3
“由于嵌入式C ++空间软件中的任何运行时错误都可能使任务崩溃(再次阅读有关Ariane 5的首次飞行失败的消息,”尽管如此,这也不是支持嵌入式空间C的理由。C++具有更强大的类型检查功能,在这种情况下有所帮助
Tarick Welling

2
我发现这些有关C ++语言复杂性的论点令人信服。如果选择的语言是C,则它们将是有效的。但是我在某处读到Ada是他们的首选语言,并且它也是一种复杂的语言,我认为可以与C ++相提并论(尽管我承认我从未真正使用过它,但我只是在80年代开发时才读过该规范。 )。
Barmar

8
我发现您的C ++模板示例是std::map<std::string,long>,这令人怀疑,然后您出于动态分配的原因而不是因为它是模板而反对它。我猜您想对动态分配进行详细介绍,因为OP在介绍了代码膨胀的模板之后也提到了动态分配,这是使验证变得更加困难的一般复杂性的一部分。它可以安全地使用模板,如果你认为你在做什么,但肯定很容易得到代码膨胀。
彼得·科德斯

3
回复:安全关键系统上的锈蚀:iron-systems.com/blog/sealed-rust-the-pitch
Sebastian Redl

7
这与模板有何关系?
Reuven Abliyev '19

8

反对在安全代码中使用模板的观点是,认为模板会增加代码的复杂性而没有真正的好处。如果您使用的工具不好并且有经典的安全性概念,则此论点是有效的。请看以下示例:

template<class T>  fun(T t){
   do_some_thing(t);
}

用经典的方式来指定安全系统,您必须提供代码的每个功能和结构的完整描述。这意味着没有规范就不允许有任何代码。这意味着您必须以常规形式完整描述模板的功能。由于明显的原因,这是不可能的。顺便说一句,同样的原因也禁止类似函数的宏。如果您以描述此模板的所有实际实例的方式改变了想法,则可以克服此限制,但是您需要适当的工具来证明您确实描述了所有模板。

第二个问题是:

fun(b);

这条线不是独立的线。您需要查找b的类型以知道实际调用了哪个函数。理解模板的正确工具在这里有帮助。但是在这种情况下,确实使手动检查代码变得更加困难。


1
同意,但我的答案建议先于您的答案。嵌入式C ++软件的手动测试确实太昂贵了。你不能多阿丽亚娜5型火箭的飞行试验像它的501
巴西莱Starynkevitch

4
“反对在安全代码中使用模板的论点是,认为模板会增加代码的复杂性而没有真正的好处。” 不,这是反对在整体嵌入式系统中使用模板的争论。反对在安全代码中使用模板的观点是,对于100%确定性代码中的模板,没有任何使用。在这样的系统中,任何地方都没有通用的编程。您不能使用std :: vector之类的东西,因为您不太可能找到符合安全标准的std lib。否则,将花费大量现金。
隆丁

3
@Lundin嵌入式世界中的泛型编程是一回事。甚至是深入的嵌入式东西。对于相同的原因,为什么它已成为其他方面的事情:经过良好测试的算法是一件好事。
user6556709

2
@Lundin:模板与确定性或非确定性代码无关。最后,它们只是在没有动态分配(虚拟函数或函数指针)且没有复制粘贴代码的情况下重用代码的一种方法,同时比宏要安全一些。例如,重复使用相同的排序算法来对整数数组和短裤数组进行排序。而且std :: vector不适合对安全性要求很高的实时代码这一事实与它作为模板无关。
MikeMB

1
谁做?通用算法库的作者可能就是这种情况,但是当我们谈论安全关键的实时代码时,无论如何我们都离开了“通用”域,OP也明确地谈论了针对目的的定制模板。
MikeMB

1

在我看来,有关模板是导致漏洞的原因的说法似乎完全是超现实的。主要有两个原因:

  • 模板被“编译掉”,即像任何其他函数/成员一样被实例化和代码生成,并且没有特定于它们的行为。就像它们从未存在过一样;

  • 任何语言的建筑都不是安全或脆弱的;如果电离粒子更改了单个内存(无论是代码还是数据),一切皆有可能(从无明显问题到处理器崩溃)。屏蔽系统的方法是添加硬件内存错误检测/纠正功能。不能通过修改代码!


因此,您既信任C ++编译器前端最复杂的部分,又信任定义模板的代码。您如何详尽地测试它们两者?当然,无关于任何宇宙射线切换位
巴西莱Starynkevitch

顺便说一句,这更像是评论(很有趣)而不是答案
Basile Starynkevitch

@BasileStarynkevitch:不,这是一个明确的答案,即模板与宇宙射线无关。循环,不安全的强制转换,缺乏文档和程序员的年龄也不是。
Yves Daoust

我可能不同意第二点。我记得曾经读过一些声称检测内核代码中的位变化的学术论文。我真的忘记了细节,因为那个话题让我不感兴趣。BTW Guillaume D.对防辐射嵌入式系统与动态分配之间关系的理解过于简单(我希望我们都同意)
Basile Starynkevitch

1
@BasileStarynkevitch:我们不是在讨论您的个人利益,而是帮助OP处理辐射的方法。
伊夫·戴乌斯特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.