Pregunta

Mientras trabajaba en un proyecto reciente, fui visitado por un cliente QA representante, quien me hizo una pregunta que yo realmente no había considerado antes:

¿Cómo saber que el compilador utiliza genera código máquina que coincida con el código c de la funcionalidad exactamente y que el compilador es totalmente determinista?

A esta pregunta yo no tenía absolutamente ninguna respuesta como siempre he llevado el compilador por sentado.Toma en código y vomita en código de máquina.Cómo se puede ir sobre y la prueba de que el compilador no es en realidad la adición de la funcionalidad que no he preguntado por?o incluso más peligroso de ejecución de código en una forma ligeramente diferente a la que me espera?

Soy consciente de que este es perhapse no es realmente un problema para todo el mundo, y de hecho la respuesta sólo podría ser..."estás más de un barril y tratar con él".Sin embargo, cuando se trabaja en un entorno integrado, usted confía en tu compilador implícitamente.¿Cómo puedo probarme a mí mismo y de control de calidad que tengo razón en hacerlo?

¿Fue útil?

Solución

Para los críticos de seguridad de aplicaciones incrustadas agencias de acreditación requieren para satisfacer la "probada-en-uso" requisito para el compilador.Normalmente, hay ciertos requisitos (una especie de "horas de funcionamiento") que deben cumplirse y probado por la documentación detallada.Sin embargo, la mayoría de la gente no puede o no quiere cumplir con estos requisitos, ya que puede ser muy difícil, especialmente en su primer proyecto con un nuevo destino/compilador.

Otro enfoque es básicamente para NO confiar en el compilador de la salida.Cualquier compilador e incluso el lenguaje-dependiente (Apéndice G de la C-90 estándar, ¿alguien?) las deficiencias deben ser cubiertos por un estricto conjunto de análisis estático, la unidad y la cobertura de las pruebas además de las posteriores pruebas funcionales.

Un estándar como MISRA-C puede ayudar a restringir la entrada al compilador a un lugar "seguro" subconjunto del lenguaje C.Otro enfoque es el de restringir la entrada a un compilador para un subconjunto de un lenguaje y una prueba de lo que el resultado para todo subconjunto es.Si nuestra aplicación está construido sólo de los componentes del subconjunto que se supone conocido lo que la salida del compilador será.El por lo general pasa por "calificación del compilador".

El objetivo de todo esto es ser capaz de responder a las QA representante de la pregunta con "no sólo se basan en el determinismo del compilador, pero esta es la manera de demostrarlo...".

Otros consejos

Usted puede solicitar que el argumento a cualquier nivel:¿usted confía en las bibliotecas de terceros?¿usted confía en el sistema operativo?¿confía en que el procesador?

Un buen ejemplo de por qué esto puede ser una preocupación válida, por supuesto, es lo de Ken Thompson puso una puerta trasera en el original de 'inicio de sesión' programa de ...y modificado el compilador de C de modo que incluso si usted vuelve a compilar de inicio de sesión, usted todavía tiene la puerta trasera.Ver este la publicación de para obtener más detalles.

Preguntas similares se han planteado sobre algoritmos de cifrado -- ¿cómo sabemos que no hay una puerta trasera en la DES para la NSA para espiar a través de?

Al final de la que usted tiene que decidir si confía en la infraestructura que se construye sobre lo suficiente como para no preocuparse por ella, de lo contrario tienes que empezar a desarrollar su propio chips de silicio!

Usted sabe que por las pruebas.Cuando se prueba, tienes que probar tu código y el compilador.

Usted encontrará que las probabilidades de que usted o el compilador escritor ha cometido un error son mucho más pequeños que las probabilidades de que sería un error si escribimos el programa en cuestión en algún lenguaje ensamblador.

Hay compilador de validación de los trajes disponibles.
El que yo recuerdo es "Perenne".

Cuando yo trabajaba en un compilador de C para una incrustado procesador SOC hemos tenido que validar el compilador en contra de este y otros dos de validación de los palos (que se me olvida el nombre).Validar el compilador para un cierto nivel de cumplimiento de estas pruebas de los trajes era parte del contrato.

Todo se reduce a la confianza.¿Su cliente confíe en cualquier compilador?Uso, o al menos comparar el código de salida entre la tuya y la de ellos.

Si no confían en ninguna, hay una implementación de referencia para el idioma?Podría convencer a confiar en ella?A continuación, comparar el suyo en contra de la referencia o el uso de la referencia.

Todo esto suponiendo que en realidad verificar el código real que se obtiene de la vendedor/proveedor y que compruebe que el compilador no ha sido manipulado, que debe ser el primer paso.

De todos modos esto todavía deja la pregunta acerca de cómo podría usted comprobar, sin tener referencias, un compilador, a partir de cero.Que sin duda se ve como un montón de trabajo y requiere de una definición de la lengua, que no siempre está disponible, a veces, la definición es el compilador.

¿Cómo saber que el compilador utiliza genera código máquina que coincida con el código c de la funcionalidad exactamente y que el compilador es totalmente determinista?

No, es por eso que usted prueba el binario resultante, y por qué usted asegúrese de enviar el mismo binario que probada.Y por qué cuando se hace de la 'menor' cambios en el software, usted regresión de prueba para asegurarse de que ninguno de los viejos funcionalidad de la quiebra.

El único software que he certificado es aviónica.La certificación de la FAA no es lo suficientemente riguroso como para demostrar que el software funciona correctamente, mientras que al mismo tiempo le obligará a saltar a través de una cierta cantidad de aros.El truco está en la estructura de su 'proceso', de modo que se mejora la calidad tanto como sea posible, con tan poco extraño aro de salto como usted puede conseguir lejos con.Así que cualquier cosa que usted sabe que es inútil, y en realidad no va a encontrar errores, usted probablemente puede escabullirse de.Y algo que usted sabe que debe hacer, porque es se encontrar errores que no se pide explícitamente por la FAA, su mejor apuesta es retorcer las palabras hasta que suena como que usted está dando a la FAA/su gente de calidad lo que pedían.

Esto en realidad no es tan deshonesto como lo he hecho en el sonido, en general, la FAA se preocupa más acerca de usted ser conscientes y seguros de que usted está tratando de para hacer un buen trabajo, que acerca de qué es exactamente lo que hacer.

Algunos munición intelectual puede ser encontrado en la Interferencia, una revista para la defensa de los ingenieros de software.Esta pregunta es el tipo de cosas que pasan muchas horas de vigilia en. http://www.stsc.hill.af.mil/crosstalk/2006/08/index.html (Si no puedo encontrar mis viejos apuntes de un viejo proyecto, voy a estar de vuelta por aquí...)

Nunca se puede confiar plenamente en el compilador, incluso altamente recomendadas.Se podría lanzar una actualización que tiene un error, y el código se compila el mismo.Este problema se agrava cuando la actualización de código antiguo con el buggy compilador, haciendo pruebas y expedición de las mercancías sólo para que el cliente anillo de 3 meses más tarde con un problema.

Todo vuelve a probar, y si hay una cosa que he aprendido es profundamente prueba después de no trivial de cambio.Si el problema parece imposible encontrar a echar un vistazo a esta recopilación de ensamblador y compruebe que está haciendo lo que debe hacer.

En varias ocasiones he encontrado errores en el compilador.Una vez hubo un error en el que 16 bits variables conseguir incrementa, pero sin llevar y sólo si el de 16 bits variable fue parte de un extern struct definida en un archivo de encabezado.

...la confianza en su compilador implícitamente

Vas a dejar de hacer que la primera vez que vienen a través de un bug del compilador.;-)

Pero en última instancia esto es lo que la prueba es para el.No importa para su prueba régimen de cómo el error que tienes en tu producto, en primer lugar, todo lo que importa es que no pase de su extensa régimen de pruebas.

Bueno..no se puede decir simplemente que usted confía en tu compilador de salida - especialmente si usted trabaja con código embebido.No es difícil encontrar discrepancias entre el código generado al compilar el mismo código con diferentes compiladores.Este es el caso debido a que el estándar de C en sí es demasiado flojo.Muchos detalles se pueden implementar de manera diferente por diferentes compiladores sin romper la norma.¿Cómo podemos lidiar con esto?Evitamos dependiente del compilador construcciones siempre que sea posible.Podemos tratar con él por la elección de un seguro subconjunto de C, como Misra-C como se mencionó anteriormente por el usuario cschol.Yo rara vez tienen que inspeccionar el código generado por el compilador, sino que también ha sucedido a mí a veces.Pero, en última instancia, usted está confiando en sus pruebas con el fin de asegurarse de que el código se comporta según lo previsto.

Existe una mejor opción que existe?Algunas personas afirman que hay.La otra opción es escribir el código en SPARK/Ada.Nunca he escrito el código en la CHISPA, pero mi entendimiento es que usted todavía tiene que vincular en contra de rutinas escritas en C que lidiar con el "bare metal" cosas.La belleza de la CHISPA/Ada es que está absolutamente garantizado que el código generado por cualquier compilador siempre va a ser el mismo.No hay ambigüedad alguna.En la parte superior de que el lenguaje le permite anotar el código con explicaciones de cómo el código es la intención de comportarse.La CHISPA conjunto de herramientas va a utilizar estas anotaciones para demostrar formalmente que el código escrito hace, de hecho, hacer lo que las anotaciones se han descrito.Por lo que me han dicho que para los sistemas críticos, SPARK/Ada es una apuesta bastante buena.Nunca he probado a mí mismo aunque.

No sabemos con certeza que el compilador va a hacer exactamente lo que usted espera.La razón es, por supuesto, que un compilador es un pedazo de software, y es por lo tanto susceptible a errores.

Compilador escritores tienen la ventaja de trabajar desde una alta calidad en la especificación, mientras que el resto de nosotros tenemos que averiguar qué es lo que estamos haciendo a medida que avanzamos.Sin embargo, el compilador de especificaciones también tiene bugs, y piezas complejas con interacciones sutiles.Así, no es exactamente trivial para averiguar lo que el compilador debería estar haciendo.

Aún así, una vez que usted decida lo que usted piensa que el lenguaje de especificación de los medios, usted puede escribir una buena, rápida y automatizada de prueba para cada matiz.Aquí es donde el compilador de la escritura tiene una gran ventaja frente a la escritura de otros tipos de software:en las pruebas.Cada error se convierte en un sistema automatizado de caso de prueba, y la prueba suite muy completa.Los proveedores de compiladores tienen mucho más presupuesto para invertir en la verificación de la corrección del compilador que usted (usted ya tiene un trabajo de día, ¿verdad?).

¿Qué significa esto para usted?Esto significa que usted necesita para estar abierto a las posibilidades de errores en el compilador, pero las probabilidades son que usted no encontrará ninguna de sí mismo.

Me volvería a escoger un proveedor de compilador que no es probable que vaya a salir del negocio en cualquier momento, el que tiene un historial de alta calidad en sus compiladores, y que ha demostrado su capacidad de servicio (revisión) de sus productos.Los compiladores parecen tener más correcto a lo largo del tiempo, así que me gustaría elegir uno que ha estado alrededor de una década o dos.

Enfoque su atención en la obtención de su código de derecho. Si es claro y simple, cuando te ¿ golpear a un error en el compilador, usted no tiene que pensar realmente difícil decidir dónde reside el problema. Escribir pruebas unitarias, que se asegurará de que el código hace lo que usted espera que haga.

Trate de pruebas de unidad.

Si eso no es suficiente, el uso de diferentes compiladores y comparar los resultados de sus pruebas de unidad.Comparar strace salidas, ejecutar las pruebas en una máquina virtual, mantener un registro de disco y de red de e/S, a continuación, compare los.

O proponer a escribir su propio compilador y decirles lo que va a costar.

La mayoría de los que fácilmente se puede certificar es que usted está utilizando una untampered compilador de proveedor X.Si no confían proveedor de X, es su problema (si X es razonablemente confiable).Si no confían cualquier compilador proveedor, entonces ellos son completamente irracional.

Respondiendo a su pregunta:Me aseguro de que estoy usando un untampered compilador de X a través de estos medios.X es conocido, además de que tiene un buen conjunto de pruebas que muestran que nuestra aplicación se comporta como se espera.

Todo lo demás está comenzando a abrir la lata de gusanos.Usted tiene que parar en algún lugar, como dice Rob.

A veces usted consigue cambios de comportamiento cuando usted solicita agresivo niveles de optimización.

Optimización y números de punto flotante?Olvidarse de él!

Para la mayoría de los de desarrollo de software (creo que las aplicaciones de escritorio), la respuesta es probablemente que usted no sabe y no le importa.

En la seguridad de los sistemas críticos (creo que las plantas de energía nuclear y comercial de la aviónica) que ¿ la atención y las agencias reguladoras se requieren para demostrarlo.En mi experiencia, usted puede hacer esto de dos maneras:

  1. El uso de un calificado compilador, donde "calificado" significa que se ha verificado de acuerdo a los estándares establecidos por el organismo regulador.
  2. Realizar el objeto de análisis de código.Esencialmente, se compila un trozo de código de la referencia y, a continuación, analizar manualmente la salida de demostrar que el compilador no se ha insertado ninguna de las instrucciones que no se pueden remontar de nuevo a su código fuente.

Usted consigue el de Dijkstra escribió.

Seleccione una verificado formalmente compilador, como Compcert C compilador.

  1. Cambiar el nivel de optimización del compilador va a cambiar el resultado.
  2. Ligeros cambios para una función puede hacer que el compilador en línea o no en línea de una función.
  3. Cambios en el compilador (gcc, por ejemplo) puede cambiar la salida de
  4. Ciertas funciones de la biblioteca puede ser instrinic (es decir, emiten optimizado de la asamblea), mientras que otros la mayoría no lo son.

La buena noticia es que para la mayoría de las cosas que realmente no importa mucho.Cuando esto ocurre, es posible que desee considerar la asamblea si es realmente importante (por ejemplo, en un ISR).

Si usted está preocupado acerca de la inesperada código de máquina que no produce resultados visibles, la única manera es, probablemente, contacto con los proveedores del compilador para la certificación de algún tipo que va a satisfacer a su cliente.

De lo contrario, usted sabrá que es el mismo que usted sabe acerca de los errores en el código de pruebas.

Código máquina a partir de los compiladores modernos, puede ser muy diferente y totalmente incomprensible para los insignificantes humanos.

Creo que es posible reducir este problema a la Detener Problema de alguna manera.

El problema más obvio es que si se usa algún tipo de programa para analizar el compilador y su determinismo, ¿cómo sabes que su programa se compila correctamente, y produce el resultado correcto?

Si usted está usando otro, "seguro" del compilador, aunque, no estoy seguro.Lo que estoy seguro es escribir un compilador desde cero probablemente sería un trabajo más fácil.

Incluso un calificado o certificado compilador puede producir resultados no deseados.Mantener el código simple y prueba, prueba, prueba.Que camina por el código de la máquina con la mano mientras no permitir que cualquier error humano.Además el sistema operativo o cualquier entorno en el que se están ejecutando en (preferiblemente sin sistema operativo, solo el programa).

Este problema ha sido resuelto en entornos de misión crítica desde el software de programación y compiladores comenzó.Como muchos de los otros que han respondido también sabe.Cada industria tiene sus propias normas de certificación de los compiladores para el estilo de programación (siempre debe de programa de esta manera, no utilice este o ese o el otro), un montón de pruebas y revisión por pares.La verificación de cada ruta de ejecución, etc.

Si usted no está en una de esas industrias, a continuación, usted consigue lo que usted consigue.Un programa comercial en una de las CUNAS del sistema operativo en el hardware COTS.Se producirá un error, que es una garantía.

Si su preocupados por malintencionado errores en el compilador, una recomendación (si mal no recuerdo, una de la NSA requisito para algunos proyectos) es que el compilador binarias son anteriores a la escritura del código.Por lo menos ya sabes que nadie tiene agregó errores dirigido a su programa.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top