c++ embedded fault-tolerance

¿Por qué no se recomienda el uso de plantillas de C++ en un espacio/entorno radiado?



embedded fault-tolerance (2)

¿Por qué no se recomienda el uso de plantillas de C ++ en el espacio / entorno radiado?

Esa recomendación es una generalización , a C ++, de las reglas de codificación de MISRA C y de las reglas de C ++ Embedded , y de DO178C recomendaciones de DO178C , y no está relacionada con la radiación, sino con los sistemas integrados. Debido a las restricciones de radiación y vibración, el hardware integrado de cualquier computadora de cohete espacial tiene que ser muy pequeño (por ejemplo, por razones económicas y de consumo de energía, es más -en el poder de la computadora- un sistema tipo Raspberry Pi que un gran sistema de servidor x86 ). Los chips endurecidos al espacio cuestan 1000x tanto como sus homólogos civiles. Y calcular el WCET en WCET con espacio incorporado sigue siendo un desafío técnico (por ejemplo, debido a problemas relacionados con la memoria caché de la CPU ). Por lo tanto, la asignación de pilas está mal vista en safety-critical sistemas de software integrado que son safety-critical (¿cómo manejaría las condiciones de falta de memoria en estos? ¿O cómo demostraría que tiene suficiente RAM para todos los casos de tiempo de ejecución real?)

Mire también en Frama-Clang y CompCert y observe lo siguiente:

  • C ++ 11 (o lo que sigue) es un lenguaje de programación horriblemente complejo . No tiene semántica formal completa. La gente lo suficientemente experta en C ++ son solo unas pocas docenas en todo el mundo (probablemente, la mayoría de ellos están en su comité estándar). Soy capaz de codificar en C ++, pero no de explicar todos los casos de esquinas sutiles de la semántica de movimientos o del modelo de memoria de C ++. Además, C ++ requiere en la práctica muchas optimizaciones para ser utilizadas de manera eficiente.

  • Es muy difícil hacer un compilador de C ++ sin errores , en particular porque C ++ prácticamente requiere optimizations complicadas, y debido a la complejidad de la especificación de C ++. Pero los actuales (como los recientes GCC o Clang) son bastante buenos en la práctica, y tienen pocos (pero aún algunos) errores de compilación residual. Todavía no hay CompCert ++ para C ++, y hacer uno requiere varios millones de € o US $ (pero si puede cobrar esa cantidad de dinero, comuníquese me por correo electrónico, por ejemplo, a [email protected] , mi correo electrónico del trabajo ). Y la industria del software espacial es extremadamente conservadora.

  • Es difícil hacer un buen asignador de memoria de pila C o C ++ . Codificar uno es una cuestión de compensaciones. Como broma, considere la posibilidad de adaptar este asignador de pila C a C ++.

  • La demostración de las propiedades de seguridad (en particular, la falta de condiciones de carrera o el comportamiento indefinido , como el desbordamiento del búfer en el tiempo de ejecución) del código C ++ relacionado con la plantilla aún está, en el 2T2019, ligeramente por delante del estado del arte del análisis de programas estáticos del código C ++ . Mi borrador del informe técnico de Bismon (es un borrador del producto H2020, por lo tanto, omita las páginas para burócratas europeos) tiene varias páginas que explican esto con más detalles. Sé consciente del teorema de Rice .

  • una prueba de software integrado C ++ de todo el sistema podría requerir un lanzamiento de cohete (como el vuelo de prueba 501 de Ariane 5 , o al menos una experimentación compleja y pesada en un laboratorio). Es muy caro Incluso probando, en la Tierra, un rover de Marte toma mucho dinero.

Piénselo: está codificando algún software integrado que es crítico para la seguridad (por ejemplo, para frenos de trenes, vehículos autónomos, drones autónomos, gran plataforma petrolera o refinería de petróleo, misiles, etc.). Utiliza ingenuamente algún contenedor estándar de C ++, por ejemplo, std::map<std::string,long> . ¿Qué debería suceder con las condiciones de falta de memoria? ¿Cómo "prueba", o al menos "convence", a las personas que trabajan en organizaciones que financian un cohete espacial de 100 millones de euros, que su software integrado (incluido el compilador utilizado para construirlo) es suficientemente bueno? Una regla de una década de antigüedad era prohibir cualquier tipo de asignación dinámica de almacenamiento dinámico.

No estoy hablando de cosas complejas de la biblioteca estándar, sino de plantillas personalizadas hechas a medida.

Incluso estos son difíciles de probar , o más generalmente para evaluar su calidad (y probablemente querrá usar su propio allocator dentro de ellos). En el espacio, el espacio del código es una fuerte restricción. Así que compilarías con, por ejemplo, g++ -Os -Wall o clang++ -Os -Wall . Pero, ¿cómo probó -o simplemente probó- todas las optimizaciones sutiles realizadas por -Os (y estas son específicas de su versión de GCC o de Clang)? Su organización de financiación espacial le preguntará eso, ya que cualquier error de tiempo de ejecución en el software espacial C ++ integrado puede bloquear la misión (lea nuevamente sobre la falla del primer vuelo de Ariane 5 , codificada en un dialecto de Ada que en ese momento tenía un "mejor" y Sistema de tipo "más seguro" que el C ++ 17 en la actualidad), pero no se ría demasiado de los europeos. Boeing 737 MAX con su MACS es un lío similar ).

Mi recomendación personal (pero, por favor, no lo tome demasiado en serio. En 2019 es más un juego de palabras que cualquier otra cosa) sería considerar la codificación de su software integrado en Rust . Porque es un poco más seguro que C ++. Por supuesto, tendrá que gastar de 5 a 10 M € (o MUS $) en 5 o 7 años para obtener un excelente compilador de Rust, adecuado para computadoras espaciales (nuevamente, contácteme profesionalmente, si es capaz de gastarlo). mucho en un software libre Compcert / Rust como compilador). Pero eso es solo una cuestión de ingeniería de software y gestión de proyectos de software (lea los trabajos de Mythical Man-Month y Bullshit para obtener más información, tenga en cuenta el principio de Dilbert : se aplica tanto a la industria de software espacial como a la industria de compiladores integrados, como a Algo más).

Mi opinión personal y firme es que la Comisión Europea debería financiar (por ejemplo, a través de Horizon Europe ) un proyecto gratuito CompCert ++ (o, mejor aún, un proyecto similar a Compcert / Rust) (y tal proyecto necesitaría más de 5 años y más de 5) -clase, investigadores de doctorado). Pero, a la edad de 60 años, lamentablemente sé que no va a suceder (porque la ideología de la CE, principalmente inspirada en las políticas alemanas por razones obvias) sigue siendo la ilusión del fin de la historia , por lo que H2020 y Horizon Europe son, en práctica, principalmente una forma de implementar optimizaciones fiscales para corporaciones en Europa a través de paraísos fiscales europeos), y después de varias discusiones privadas con varios miembros del proyecto CompCert. Lamentablemente, espero que DARPA o la NASA tengan muchas más probabilidades de financiar algún proyecto futuro CompCert / Rust (que la financiación de la CE).

NÓTESE BIEN. La industria de aviónica europea (en su mayoría Airbus) está utilizando métodos mucho más formales que el norteamericano (Boeing). Por lo tanto, se evitan algunas (no todas) las pruebas unitarias (ya que se reemplazan por pruebas formales de código fuente, tal vez con herramientas como Frama-C o Astrée ; ninguna ha sido certificada para C ++, solo para un subconjunto de C que prohíbe la asignación de memoria dinámica C y varias Otras características de C). Y esto está permitido por DO178C (no por el antecesor DO-178B ) y aprobado por el regulador francés, DGAC (y supongo que por otros reguladores europeos).

Al leer esta pregunta , entendí, por ejemplo, por qué la asignación dinámica o las excepciones no se recomiendan en entornos donde la radiación es alta, como en el espacio o en una planta de energía nuclear. En cuanto a las plantillas, no veo por qué. ¿Me lo podrías explicar?

Teniendo en cuenta esta respuesta , dice que es bastante seguro de usar.

Nota: no estoy hablando de cosas complejas de la biblioteca estándar, sino de plantillas personalizadas específicas.


La argumentación contra el uso de plantillas en el código de seguridad es que se considera que aumentan la complejidad de su código sin un beneficio real. Esta argumentación es válida si tiene herramientas incorrectas y una idea clásica de seguridad. Tomemos el siguiente ejemplo:

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

En la forma clásica de especificar un sistema de seguridad, debe proporcionar una descripción completa de cada una de las funciones y la estructura de su código. Eso significa que no se le permite tener ningún código sin especificación. Eso significa que debe proporcionar una descripción completa de la funcionalidad de la plantilla en su forma general. Por razones obvias eso no es posible. Esa es, por cierto, la misma razón por la que las macros similares a funciones también están prohibidas. Si cambia la idea de manera que describa todas las instancias reales de esta plantilla, supera esta limitación, pero necesita las herramientas adecuadas para probar que realmente las describió todas.

El segundo problema es que uno:

fun(b);

Esta línea no es una línea autocontenida. Debe buscar el tipo de b para saber a qué función se llama en realidad. Las herramientas adecuadas que entienden las plantillas ayudan aquí. Pero en este caso es cierto que hace que el código sea más difícil de verificar manualmente.