¿Cómo podemos estar seguros de que los componentes inferiores de la programación de computadoras, como compiladores, ensambladores, instrucciones de máquinas, etc., son impecables?

58

Dado que cada vez dependemos más de la informática, incluidas las tareas críticas de la vida cotidiana, me preguntaba cómo se prueban esos componentes vitales.

Más técnicamente, ¿cómo se prueban los compiladores y los ensambladores? (Supongo que esto se relaciona con el problema de detención !!)

    
pregunta Sudip Bhandari 29.12.2015 - 16:38

8 respuestas

105

No puedes estar seguro, pero solo asumes que lo son, hasta que descubres que no lo están. Se han producido muchos errores en compiladores y hardware a lo largo de los años.

La forma en que se prueban, por ejemplo, un compilador, es que están definidas de manera muy estrecha y rígida, escritas con cuidado y luego probadas con un conjunto de pruebas enorme para verificar su exactitud. Agregue a eso la amplia base de usuarios de un compilador, y se detectarán e informarán más errores. Una aplicación de programación de citas con el dentista, comparativamente, tiene muchos menos usuarios y menos aún que son capaces de detectar defectos.

SQLite consta de aproximadamente 73k líneas de código, mientras que su conjunto de pruebas consta de aproximadamente 91378k líneas de código, más de 1250 veces más que SQLite. Espero que los compiladores y otras herramientas básicas tengan proporciones similares. Los procesadores de hoy en día están diseñados esencialmente con software, utilizando lenguajes de descripción de hardware como Verilog o VHDL, y también se ejecutan pruebas de software en ellos, así como pines IO especializados para ejecutar autopruebas en el punto de fabricación.

En última instancia, es un juego de probabilidad, y las pruebas repetidas y de cobertura amplia le permiten reducir la probabilidad de defectos a un nivel aceptablemente bajo, al igual que otro proyecto de software.

    
respondido por el whatsisname 29.12.2015 - 20:07
46

En términos sencillos:

  1. No puedes.
  2. Los compiladores e intérpretes se prueban por unidades como cualquier otro software (profesional).
  3. Una prueba exitosa no significa que un programa esté libre de errores, solo significa que no se detectaron errores.
  4. Una base de usuarios amplia que usa el compilador durante mucho tiempo es un buen indicador de que tiene muy pocos errores, porque los usuarios generalmente prueban casos en los que los diseñadores no pensaron.
  5. Ser de código abierto también es un buen indicador. "Dados suficientes globos oculares, todos los errores son superficiales ... Dados un beta-tester y una base de desarrolladores adecuados, casi todos los problemas se caracterizará rápidamente y la solución será obvia para alguien ". . Un compilador de código cerrado podría tener errores que surgen en momentos muy específicos o que generan menos de un código de máquina óptimo y la compañía detrás de él simplemente podría no revelar su existencia y darle una prioridad muy baja en la hoja de ruta del producto. li>

Bottom-line:

Yo diría que vaya por OOP ( O ld, O pluma y P opular). Acabo de hacer ese acrónimo.

    
respondido por el Tulains Córdova 29.12.2015 - 20:01
24

Son tortugas hasta el fondo.

Nada es cierto. No tiene más remedio que conformarse con las calificaciones de confianza.

Puedes considerarlo como una pila: Matemáticas > Física > Hardware > Firmware y gt; Sistema operativo > Ensamblador / Compilador / etc

En cada nivel tiene pruebas que puede realizar para mejorar sus calificaciones de confianza. Algunas de estas pruebas tienen la calidad de pruebas formales, algunas de ellas se basan en la observación, la mayoría son una combinación de ambas.

La parte difícil es desentrañar la recursión en algunas de estas pruebas porque usamos programas para hacer pruebas y análisis observacionales ahora donde se ha vuelto demasiado difícil hacerlo a mano.

En última instancia, aunque la respuesta es que intentas todo lo que puedas imaginar. Análisis estático, fuzzing, simulación, ejecución con entradas extremas o entradas aleatorias seleccionadas a propósito, ejecución / mapeo de cada ruta de control, pruebas formales, etc. Básicamente, su objetivo en las pruebas debe ser hacer todo lo posible para demostrar que su producto (por ejemplo, teoría / chip / programa) no funciona según lo previsto. Si realiza un esfuerzo genuino y sigue fallando, se le permite mejorar su calificación de confianza en la corrección de su producto.

Las pruebas son, en el mejor de los casos, un proceso de semidecisión, lo que significa que, dado que hay un error, eventualmente lo encontrará, pero nunca puede estar seguro de haberlo encontrado todo. Incluso con el software verificado formalmente, usted sigue confiando en la física, las herramientas utilizadas para hacer las pruebas formales, y que lo que demostró es necesario y suficiente para que su programa haga lo que se pretende (a menudo subjetivamente). Eso no quiere decir que todos los demás componentes que está utilizando no tienen pruebas formales.

    
respondido por el voutasaurus 30.12.2015 - 05:55
17

Esta es una pregunta "peligrosa" para los nuevos desarrolladores, ya que comenzarán a echarle la culpa a sus herramientas en lugar de a su código (ya sea, hecho eso, visto que muchos lo hacen). Aunque hay errores en compiladores, entornos de ejecución, sistemas operativos, etc., los desarrolladores deben ser realistas y recordar que, hasta que haya pruebas y pruebas de unidad que demuestren lo contrario, el error está en su código .

En más de 25 años de programación, principalmente en C, C ++ y Java, he encontrado:

  • dos errores debido a un error del compilador (gcc y SunOS C)
  • aproximadamente una vez cada año o dos un error debido a un problema de Java JVM (generalmente relacionado con el consumo de memoria / recolección de basura)
  • aproximadamente una vez por mes o dos, un error en una biblioteca, que a menudo se corrige con la última versión o volviendo a la versión anterior de la biblioteca

Todos los otros errores están relacionados directamente con un error o, más frecuentemente, una falta de comprensión de cómo funciona una biblioteca. A veces, lo que parece ser un error se debe a una incompatibilidad, por ejemplo, cómo cambió la estructura de la clase Java que rompió algunas bibliotecas AOP.

    
respondido por el Ed Griebel 30.12.2015 - 20:05
8

Creo que un punto interesante aquí es que la gran mayoría de las licencias de software comercial (y de hecho de código abierto) especifican específicamente que no se puede confiar en el software.

  

EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍAS DE NINGÚN TIPO, EXPRESAS O IMPLÍCITAS, INCLUIDAS, PERO NO LIMITADAS A LAS GARANTÍAS DE COMERCIABILIDAD, APTITUD PARA UN PROPÓSITO PARTICULAR Y NO INFLUENCIA.

Del acuerdo de licencia de Microsoft Word

  

. Con excepción de la Garantía limitada y en la medida máxima permitida por la ley aplicable, Microsoft y sus proveedores proporcionan el Software y los servicios de soporte (si corresponde) TAL CUAL Y CON TODAS LAS FALLAS, y por la presente renuncia a todas las demás garantías y condiciones, ya sean expresas, implícitas o estatutario, incluyendo, pero no limitado a, cualquier (si existe) garantía implícita, deberes o condiciones de comercialización, de aptitud para un propósito particular, de confiabilidad o disponibilidad, de precisión o integridad de respuestas, de resultados, de esfuerzo profesional, de la falta de virus y la falta de negligencia, todo con respecto al Software, y la provisión o falla en la prestación de soporte u otros servicios, información, software y contenido relacionado a través del Software o de otro modo que surja del uso del Software .

Básicamente, esta oración en la licencia en casi todos los programas de software que usas específicamente te dice que no puedes confiar en el software, y mucho menos en el compilador utilizado.

El software es como una teoría científica, se considera que funciona como se especifica hasta que no funciona.

    
respondido por el Toby Allen 30.12.2015 - 11:24
2

Como compilador de un lenguaje matemático *, por mi experiencia, puedo decir en teoría que no puedes. Y algunos de los errores simplemente dan resultados incorrectos como (de mi verguenza lista) calcular 6/3*2 desde el derecho 6/(3*2) y generar 1 sin fallar o dar errores de compilación sin sentido.

Pero en mi humilde opinión muchos compiladores no tienen tantos errores como otros programas porque:

  • Escribir pruebas unitarias es fácil. Cada declaración es una unidad y puede escribir pruebas tan simples como: test_unit("2+(-2)*(-2+1)*3+1",9);
  • Un programa es una combinación de declaraciones y para que cualquier programa produzca el resultado correcto, cada declaración individual debe proporcionar el resultado correcto (en su mayoría). Por lo tanto, es muy poco probable que tenga errores mientras el programa da el resultado correcto.
  • A medida que aumenta el tamaño y la cantidad de programas escritos, aumenta la probabilidad de que se detecten errores.

Para los ensambladores, las instrucciones de la máquina, etc., lo anterior también es válido; por otro lado, la verificación y validación en el diseño y producción de chips tienen procesos mucho más estrictos, ya que es un gran negocio: Automatización de diseño electrónico .

Antes de ir a la producción, cada CPU debe probarse rigurosamente porque cada error cuesta casi un par de millones de dólares: hay enormes costos de producción no recurrentes en la producción de chips. Así que las empresas gastan mucho dinero y escriben muchos códigos de simulación para su diseño antes de comenzar la producción, aunque esto no ofrece una garantía del 100%, por ejemplo: el error Pentium FDIV.

En resumen, es muy poco probable que tenga errores graves en compiladores, códigos de máquina, etc.

Mi humilde lenguaje matemático *

    
respondido por el Gorkem 30.12.2015 - 10:39
0

Impecable? Ellos no están. Recientemente instalé algunas "actualizaciones", y pasaron meses (y varias secciones de código reprogramadas) más tarde antes de que mi sitio ASP.NET volviera a funcionar correctamente, debido a cambios inexplicables en la forma en que funcionaban o fallaban varias cosas básicas.

Sin embargo, son probados y luego son utilizados por muchas personas muy inteligentes orientadas a los detalles, que tienden a notar, reportar y arreglar la mayoría de las cosas. Stack Exchange es un gran ejemplo (y mejora) de cómo todas las personas que usan esas herramientas ayudan a probar y analizar cómo funcionan estas herramientas increíblemente complejas y de bajo nivel, al menos en lo que respecta al uso práctico.

Pero impecable, no. Aunque también puede ver a las personas en Stack Exchange obteniendo una visión impresionante de los detalles de desempeño y el cumplimiento de las normas y las peculiaridades, siempre hay fallas e imperfecciones, especialmente cuando diferentes personas tienen diferentes opiniones sobre lo que es una falla.

    
respondido por el Dronz 30.12.2015 - 07:03
-1

Para mostrar que los sistemas subyacentes son impecables, ya sea

a) Necesidad de probar que son impecables

  1. prueba matemática
  2. Solo de manera realista posible para programas triviales

b) Haz una prueba exhaustiva

  1. Solo es posible para programas triviales y algunos programas simples
  2. Tan pronto como un elemento de tiempo ingresa a la prueba, no es posible hacer una Prueba exhaustiva, ya que el tiempo se puede dividir indefinidamente.
  3. Más allá de los programas triviales, las posibles opciones de ejecución explotan exponencialmente.

En la prueba de software, la prueba exhaustiva solo se usa en la prueba unitaria de algunas funciones simples.

Ejemplo: Si desea probar una entrada de 8 caracteres de utf-8 en algún campo, debe elegir cortar la entrada a 8 veces la longitud máxima 6 de utf-8 en bytes, lo que da 8 * 6 = 48 bytes para tener realmente una cantidad finita de posibilidades.

Ahora podría pensar que solo necesita probar los 1,112,064 puntos de código válidos de cada uno de los 8 caracteres, es decir. 1,112,064 ^ 8 (digamos 10 ^ 48) pruebas (que ya es poco probable que sea posible), pero en realidad tiene que probar cada valor de cada uno de los 48 bytes o 256 ^ 48 que es alrededor de 10 ^ 120, que es la misma complejidad que < a href="https://en.wikipedia.org/wiki/Shannon_number"> chess comparado con el número total de átomos en el universo de aproximadamente 10 ^ 80.

En su lugar, puede usar, en orden creciente de esfuerzo y cada prueba debe cubrir todo lo anterior:

a) prueba una buena y una mala muestra.

b) cobertura de código, es decir. intente probar cada línea de código, que es relativamente simple para la mayoría de los códigos. Ahora puede preguntarse cuál es el último 1% del código que no puede probar: errores, código muerto, excepciones de hardware, etc.

c) cobertura de ruta, se prueban todos los resultados de todas las ramas en todas las combinaciones. Ahora sabe por qué el departamento de pruebas lo odia cuando sus funciones contienen más de 10 condiciones. También se pregunta por qué el último 1% no se puede probar ... algunas sucursales dependen de las anteriores.

d) prueba de datos, prueba un número de muestra con valor de borde, valores problemáticos comunes y números mágicos, cero, -1, 1, min +/- 1, máx +/- 1, 42, valores rnd. Si esto no le proporciona cobertura de ruta, sabe que no ha capturado todos los valores en su análisis.

Si ya haces esto, deberías estar listo para el examen de base de ISTQB.

    
respondido por el Surt 31.12.2015 - 15:30

Lea otras preguntas en las etiquetas