Un error de software es un error en el software de la computadora .
Un programa informático con muchos o graves errores puede describirse como defectuoso .
Los efectos de un error de software varían desde menores (como una palabra mal escrita en la interfaz de usuario ) hasta graves (como fallas frecuentes ).
Los errores de software se han relacionado con desastres. Los errores de software en la máquina de radioterapia Therac-25 fueron directamente responsables de las muertes de pacientes en la década de 1980. En 1996, el prototipo del cohete Ariane 5 de la Agencia Espacial Europea , valorado en mil millones de dólares, fue destruido menos de un minuto después del lanzamiento debido a un error en el programa informático de guía a bordo. [1] En 1994, un helicóptero Chinook de la RAF se estrelló , matando a 29 personas; Inicialmente se atribuyó a un error del piloto, pero luego se pensó que había sido causado por un error de software en la computadora de control del motor . [2] El software con errores provocó el escándalo de la oficina de correos británica de principios del siglo XXI . [3]
En 2002, un estudio encargado por el Instituto Nacional de Estándares y Tecnología del Departamento de Comercio de EE.UU. concluyó que "los fallos o errores de software son tan frecuentes y tan perjudiciales que le cuestan a la economía de EE.UU. aproximadamente 59 mil millones de dólares al año, o aproximadamente 0,6 por ciento del producto interno bruto". [4]
Desde la década de 1950, algunos sistemas informáticos se han diseñado para detectar o corregir automáticamente diversos errores de software durante las operaciones.
El metamorfismo del error (del griego meta = "cambio", morph = "forma") se refiere a la evolución de un defecto en la etapa final de la implementación del software. La transformación de un "error" cometido por un analista en las primeras etapas del ciclo de vida de desarrollo de software, que conduce a un "defecto" en la etapa final del ciclo, se ha denominado "metamorfismo del error". [5]
Las diferentes etapas de un error en el ciclo de desarrollo pueden describirse como error, [6] : 31 anomalía, [6] : 10 falla, [6] : 31 falla, [6] : 31 error, [6] : 31 excepción, [6] : 31 falla, [6] : 22 falla, error, [6] : 14 defecto, incidente, [6] : 39 o efecto secundario.
A veces, el uso de error para describir el comportamiento del software es polémico debido a la percepción. Algunos sugieren que debería abandonarse el término; reemplazado con defecto o error .
Algunos sostienen que error implica que el defecto surgió por sí solo y presionan para usar defecto , ya que connota más claramente que fue causado por un ser humano. [7]
Algunos sostienen que el error puede usarse para encubrir una decisión de diseño intencional. En 2011, después de recibir el escrutinio del senador estadounidense Al Franken por registrar y almacenar las ubicaciones de los usuarios en archivos no cifrados, [8] Apple calificó el comportamiento como un error. Sin embargo, Justin Brookman del Centro para la Democracia y la Tecnología cuestionó directamente esa descripción, afirmando: "Me alegro de que estén solucionando lo que ellos llaman errores, pero me opongo a su firme negación de que rastreen a los usuarios". [9]
Prevenir errores lo antes posible en el proceso de desarrollo de software es un objetivo de inversión e innovación. [10] [11]
Los lenguajes de programación más nuevos tienden a diseñarse para evitar errores comunes basados en vulnerabilidades de los lenguajes existentes. Las lecciones aprendidas de lenguajes más antiguos como BASIC y C se utilizan para informar el diseño de lenguajes posteriores como C# y Rust .
Los lenguajes pueden incluir características tales como un sistema de tipo estático, espacios de nombres restringidos y programación modular . Por ejemplo, para un lenguaje compilado y escrito (como C ):
número flotante = "3";
es sintácticamente correcto, pero falla la verificación de tipos ya que el lado derecho, una cadena, no se puede asignar a una variable flotante. La compilación falla, lo que obliga a corregir este defecto antes de que se pueda reanudar el progreso del desarrollo. Con un lenguaje interpretado, una falla no ocurriría hasta más tarde en tiempo de ejecución.
Algunos lenguajes excluyen características que fácilmente conducen a errores, a expensas de un rendimiento más lento; el principio es que generalmente es mejor escribir código correcto más simple y lento que código complicado y con errores. Por ejemplo, Java no admite la aritmética de punteros , que generalmente es rápida, pero se considera peligrosa; relativamente fácil causar un error importante.
Algunos lenguajes incluyen funciones que agregan una sobrecarga de tiempo de ejecución para evitar algunos errores. Por ejemplo, muchos lenguajes incluyen verificación de límites en tiempo de ejecución y una forma de manejar condiciones fuera de límites en lugar de fallar.
Un lenguaje compilado permite detectar algunos errores tipográficos (como un identificador mal escrito) antes del tiempo de ejecución , que es una etapa más temprana del proceso de desarrollo de software que para un lenguaje interpretado .
Las técnicas de programación, como el estilo de programación y la programación defensiva, tienen como objetivo evitar errores tipográficos.
Por ejemplo, un error puede deberse a un error tipográfico relativamente menor (error tipográfico) en el código. Por ejemplo, este código ejecuta la función foo
sólo si condition
es verdadero.
si (condición) foo();
Pero este código siempre se ejecuta foo
:
si (condición); foo();
Una convención que tiende a evitar este problema en particular es requerir llaves para un bloque incluso si tiene una sola línea.
si (condición) { foo();}
La aplicación de las convenciones puede ser manual (es decir, mediante revisión de código ) o mediante herramientas automatizadas.
Algunos sostienen que escribir una especificación de programa que establezca el comportamiento de un programa puede evitar errores.
Algunos sostienen que las especificaciones formales no son prácticas para nada que no sean los programas más cortos, debido a problemas de explosión combinatoria e indeterminación .
Uno de los objetivos de las pruebas de software es encontrar errores.
Las mediciones durante las pruebas pueden proporcionar una estimación de la cantidad de errores probables que quedan. Esto se vuelve más confiable cuanto más tiempo se prueba y desarrolla un producto. [ cita necesaria ]
El desarrollo ágil de software puede implicar lanzamientos frecuentes de software con cambios relativamente pequeños. Los defectos se revelan a través de los comentarios de los usuarios.
Con el desarrollo basado en pruebas (TDD), las pruebas unitarias se escriben mientras se escribe el código de producción, y el código de producción no se considera completo hasta que todas las pruebas se completen correctamente.
Las herramientas para el análisis de código estático ayudan a los desarrolladores al inspeccionar el texto del programa más allá de las capacidades del compilador para detectar problemas potenciales. Aunque en general el problema de encontrar todos los errores de programación dada una especificación no tiene solución (ver problema de detención ), estas herramientas explotan el hecho de que los programadores humanos tienden a cometer ciertos tipos de errores simples cuando escriben software.
Las herramientas para monitorear el rendimiento del software mientras se ejecuta, ya sea específicamente para encontrar problemas como cuellos de botella o para garantizar el funcionamiento correcto, pueden estar incorporadas explícitamente en el código (quizás tan simple como una declaración que diga PRINT "I AM HERE"
), o proporcionarse como herramientas. A menudo es una sorpresa descubrir dónde ocupa la mayor parte del tiempo un fragmento de código, y esta eliminación de suposiciones podría provocar que el código se reescriba.
El desarrollo de código abierto permite que cualquiera pueda examinar el código fuente. Una escuela de pensamiento popularizada por Eric S. Raymond como la ley de Linus dice que el software popular de código abierto tiene más posibilidades de tener pocos o ningún error que otro software, porque "con suficientes ojos, todos los errores son superficiales". [12] Sin embargo, esta afirmación ha sido cuestionada: el especialista en seguridad informática Elias Levy escribió que "es fácil ocultar vulnerabilidades en un código fuente complejo, poco comprendido e indocumentado", porque, "incluso si la gente está revisando el código, eso no Eso no significa que estén calificados para hacerlo". [13] Un ejemplo de un error de software de código abierto fue la vulnerabilidad OpenSSL de 2008 en Debian .
La depuración puede ser una parte importante del ciclo de vida del desarrollo de software . Maurice Wilkes , uno de los primeros pioneros de la informática, describió su comprensión a finales de la década de 1940 de que “una buena parte del resto de mi vida la dedicaría a encontrar errores en mis propios programas”. [14]
Un programa conocido como depurador puede ayudar a un programador a encontrar código defectuoso examinando el funcionamiento interno de un programa, como ejecutar código línea por línea y ver valores variables.
Como alternativa al uso de un depurador, el código puede instrumentarse con lógica para generar información de depuración para rastrear la ejecución del programa y ver los valores. La salida suele ser a la consola , ventana , archivo de registro o una salida de hardware (es decir, LED ).
Algunos sostienen que localizar un error es todo un arte.
No es raro que un error en una sección de un programa cause fallas en una sección diferente, [ cita necesaria ] , lo que dificulta su seguimiento, en una parte del sistema aparentemente no relacionada. Por ejemplo, un error en una rutina de representación de gráficos que provoca que falle una rutina de E/S de archivos.
A veces, la parte más difícil de la depuración es encontrar la causa del error. Una vez encontrado, corregir el problema a veces es fácil, si no trivial.
A veces, un error no es un defecto aislado, sino que representa un error de pensamiento o planificación por parte de los programadores. A menudo, un error lógico de este tipo requiere que se revise o reescriba una sección del programa.
Algunos sostienen que, como parte de la revisión del código , recorrer el código e imaginar o transcribir el proceso de ejecución a menudo puede encontrar errores sin reproducir el error como tal.
Normalmente, el primer paso para localizar un error es reproducirlo de forma fiable. Si no puede reproducir el problema, un programador no puede encontrar la causa del error y, por lo tanto, no puede solucionarlo.
Algunos errores se revelan mediante entradas que pueden resultar difíciles de recrear para el programador. Una de las causas de las muertes de la máquina de radiación Therac-25 fue un error (específicamente, una condición de carrera ) que ocurría sólo cuando el operador de la máquina entraba muy rápidamente en un plan de tratamiento; Se necesitaron días de práctica para poder hacer esto, por lo que el error no se manifestó en las pruebas ni cuando el fabricante intentó duplicarlo. Otros errores pueden dejar de ocurrir cada vez que se aumenta la configuración para ayudar a encontrar el error, como ejecutar el programa con un depurador; estos se llaman errores de Heisen (llamados humorísticamente por el principio de incertidumbre de Heisenberg ).
Desde la década de 1990, particularmente después del desastre del vuelo 501 del Ariane 5 , aumentó el interés en las ayudas automatizadas para la depuración, como el análisis de código estático mediante interpretación abstracta . [15]
A menudo, los errores surgen durante la codificación, pero la documentación de diseño defectuosa puede causar un error. En algunos casos, los cambios en el código pueden eliminar el problema aunque el código ya no coincida con la documentación.
En un sistema integrado , el software a menudo se modifica para solucionar un error de hardware, ya que es más barato que modificar el hardware.
Los errores se gestionan mediante actividades como documentar, categorizar, asignar, reproducir, corregir y publicar el código corregido.
A menudo se utilizan herramientas para rastrear errores y otros problemas con el software. Normalmente, el equipo de desarrollo de software utiliza herramientas diferentes para realizar un seguimiento de su carga de trabajo que el servicio de atención al cliente para realizar un seguimiento de los comentarios de los usuarios . [dieciséis]
Un elemento rastreado a menudo se denomina error , defecto , ticket , problema , característica o, para el desarrollo ágil de software , historia o epopeya . Los elementos suelen clasificarse por aspectos como gravedad, prioridad y número de versión .
En un proceso a veces llamado clasificación , se toman decisiones para cada error sobre si corregirlo y cuándo hacerlo en función de información como la gravedad y prioridad del error y factores externos como los cronogramas de desarrollo. La clasificación generalmente no incluye la investigación de la causa. La clasificación puede realizarse periódicamente. La clasificación generalmente consiste en revisar errores nuevos desde la clasificación anterior y tal vez todos los errores abiertos. Los asistentes pueden incluir gerentes de proyecto, gerentes de desarrollo, gerentes de pruebas, gerentes de construcción y expertos técnicos. [17] [18]
La gravedad es una medida del impacto que tiene el error. [19] Este impacto puede ser la pérdida de datos, financiera, pérdida de buena voluntad y esfuerzo desperdiciado. Los niveles de gravedad no están estandarizados, pero difieren según el contexto, como la industria y la herramienta de seguimiento. Por ejemplo, una caída en un videojuego tiene un impacto diferente que una caída en el servidor de un banco. Los niveles de gravedad pueden ser fallar o bloquearse , no hay solución alternativa (el usuario no puede realizar una tarea), tiene solución alternativa (el usuario aún puede realizar la tarea), defecto visual (un error ortográfico, por ejemplo) o error de documentación . Otro ejemplo de conjunto de gravedades: crítico , alto , bajo , bloqueador , trivial . [20] La gravedad de un error puede ser una categoría separada de su prioridad de corrección, o ambas pueden cuantificarse y gestionarse por separado.
Un error lo suficientemente grave como para retrasar el lanzamiento del producto se denomina show stopper . [21] [22]
La prioridad describe la importancia de resolver el error en relación con otros errores. Las prioridades pueden ser numéricas, como del 1 al 5, o con nombre, como crítica , alta , baja y diferida . Los valores pueden ser similares o idénticos a las clasificaciones de gravedad, aunque la prioridad sea un aspecto diferente.
La prioridad puede ser una combinación de la gravedad del error con el nivel de esfuerzo para solucionarlo. Un error de gravedad baja pero fácil de solucionar puede obtener una prioridad más alta que un error de gravedad moderada que requiere mucho más esfuerzo para solucionarlo.
Los errores de prioridad suficientemente alta pueden requerir una versión especial que a veces se denomina parche .
Una versión de software que enfatiza la corrección de errores puede denominarse versión de mantenimiento , para diferenciarla de una versión que enfatiza nuevas funciones u otros cambios.
Es una práctica común publicar software con errores conocidos de baja prioridad u otros problemas. Las posibles razones incluyen, entre otras:
La cantidad y el tipo de daño que puede causar un error de software afecta la toma de decisiones, los procesos y las políticas con respecto a la calidad del software. En aplicaciones como los vuelos espaciales tripulados , la aviación , la energía nuclear , la atención sanitaria , el transporte público o la seguridad del automóvil , dado que los fallos del software tienen el potencial de causar lesiones humanas o incluso la muerte, dicho software tendrá mucho más escrutinio y control de calidad que, por ejemplo, un sitio web de compras en línea. En aplicaciones como la bancaria, donde las fallas de software tienen el potencial de causar graves daños financieros a un banco o a sus clientes, el control de calidad también es más importante que, por ejemplo, una aplicación de edición de fotografías.
Aparte del daño causado por los errores, parte de su costo se debe al esfuerzo invertido en solucionarlos. En 1978, Lientz et al. mostró que la mediana de los proyectos invierte el 17 por ciento del esfuerzo de desarrollo en la corrección de errores. [25] En 2020, una investigación sobre los repositorios de GitHub mostró que la mediana es del 20%. [26]
En 1994, el Centro de Vuelos Espaciales Goddard de la NASA logró reducir su número promedio de errores de 4,5 por 1000 líneas de código ( SLOC ) a 1 por 1000 SLOC. [27]
Otro estudio realizado en 1990 informó que procesos de desarrollo de software excepcionalmente buenos pueden lograr tasas de falla de implementación tan bajas como 0,1 por 1000 SLOC. [28] Esta cifra se repite en literatura como Code Complete de Steve McConnell , [29] y el estudio de la NASA sobre Flight Software Complexity . [30] Algunos proyectos incluso alcanzaron cero defectos: el firmware de la máquina de escribir IBM Wheelwriter , que consta de 63.000 SLOC, y el software del transbordador espacial, con 500.000 SLOC. [28]
Para facilitar una investigación reproducible sobre pruebas y depuración, los investigadores utilizan puntos de referencia seleccionados de errores:
Algunos tipos de errores notables:
Un error puede deberse a un diseño insuficiente o incorrecto según la especificación. Por ejemplo, dado que la especificación es ordenar alfabéticamente una lista de palabras, podría ocurrir un error de diseño si el diseño no tiene en cuenta los símbolos; resultando en una alfabetización incorrecta de palabras con símbolos.
Las operaciones numéricas pueden dar como resultado resultados inesperados, procesamiento lento o fallas. [33] Tal error puede deberse a una falta de conocimiento de las cualidades del almacenamiento de datos, como una pérdida de precisión debido al redondeo , algoritmos numéricamente inestables , desbordamiento y subdesbordamiento aritmético , o a una falta de conocimiento de cómo los cálculos son manejados por diferentes lenguajes de codificación de software, como la división por cero , que en algunos idiomas puede generar una excepción y en otros puede devolver un valor especial como NaN o infinito .
Un error de flujo de control , también conocido como error lógico, se caracteriza por un código que no falla con un error, pero que no tiene el comportamiento esperado, como bucles infinitos , recursividad infinita , comparación incorrecta en un condicional , como el uso del operador de comparación incorrecto . y el error de uno por uno .
El Open Technology Institute, dirigido por el grupo New America , [38] publicó un informe "Errores en el sistema" en agosto de 2016 afirmando que los responsables políticos estadounidenses deberían realizar reformas para ayudar a los investigadores a identificar y abordar errores de software. El informe "destaca la necesidad de una reforma en el campo del descubrimiento y divulgación de vulnerabilidades de software". [39] Uno de los autores del informe dijo que el Congreso no ha hecho lo suficiente para abordar la vulnerabilidad del software cibernético, a pesar de que el Congreso ha aprobado una serie de proyectos de ley para combatir el problema más amplio de la seguridad cibernética. [39]
Los investigadores gubernamentales, las empresas y los expertos en seguridad cibernética son las personas que suelen descubrir fallas de software. El informe pide reformar las leyes sobre delitos informáticos y derechos de autor. [39]
La Ley de Abuso y Fraude Informático, la Ley de Derechos de Autor del Milenio Digital y la Ley de Privacidad de las Comunicaciones Electrónicas penalizan y crean sanciones civiles por acciones que los investigadores de seguridad realizan habitualmente mientras realizan investigaciones de seguridad legítimas, según el informe. [39]
(Cobb y Mills 1990)