安全编码实践

Gen*_*ene 2 c c++ embedded misra autosar

我正在启动一个新的 C/C++ 嵌入式应用程序,并试图让自己了解诸如 MISRA、AUTOSAR 和我目前最喜欢的安全编码实践,这可能是因为它是最短的,NASA 所谓的 10 次幂(https://en.wikipedia) .org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-Critical_Code)。我可以看到许多规则背后的逻辑。但他们都试图消除或限制动态内存分配。例如,MISRA C++ 规则 18-4-1 说:“不应使用动态堆内存分配”,而 NASA 的规则 3 是“避免堆内存分配”。AUTOSAR 的限制较少。我理解他们的意图是确保系统不会耗尽内存,但我不太清楚 C 或 C++ 编译器将什么分配为“动态堆内存分配”或“堆内存分配”。我将编辑这篇文章以提出具体问题

  1. 这是否意味着例如所有变量都需要是静态的?(已经由@klutt 回答
  2. 只是为了确保我理解正确,根据 MISRA、AUTOSAR 和 NASA 指南,临时变量是否在堆栈上声明的方法中定义并因此是“安全的”?
  3. 根据 AUTOSAR 和 NASA 指南,初始化后不能使用“new”?
  4. 根据 MISRA、AUTOSAR 和 NASA 指南,C++ 库数组是否可以?
  5. 但是根据 AUTOSAR 和 NASA 指南,不能使用像 string 和 vector 这样的 C++ 库吗?
  6. 将不胜感激任何其他“不安全”动态内存分配示例

谢谢 - 基因

And*_*rew 5

MISRA 规则的核心是动态内存分配问题

  1. 程序员天生就是懒惰的,不会检查malloc()导致使用空指针的返回状态。
  2. 堆碎片的一般问题
  3. 及其兄弟的不完整标准定义malloc(),其中充斥着未定义、未指定和实现定义的行为,这使得编译器和实现之间具有可移植性,因此行为具有一定程度的不可预测性。

MISRA C/C++ 的一些派生类(例如 JSF、NASA JPL、AUTOSAR)允许malloc()在初始化阶段(但不允许realloc()等或后续free())使用,这消除了所有碎片问题 - 但不解决不完整的定义。

当然,定制解决方案可能是完全可以证明的,在这种情况下,MISRA 规则的偏差是可以的。

但总的来说,使用动态内存的弊端超过了任何潜在的好处。

免责声明:是的,我与 MISRA 有关联……查看个人资料

  • 不使用堆分配的主要原因是:程序应该是确定性的,而且由于大多数嵌入式系统是带有裸机/RTOS 的单核 MCU,而不是在托管操作系统上运行,[使用堆没有丝毫意义](https:// electronics.stackexchange.com/a/171581/6102)。 (3认同)