Saltar al contenido
Biblioteca GKUn lugar para las mentes curiosas
Español

El bug que desaparece al examinarlo, el Heisenbug

A veces, tras recibir un aviso de que un programa falla de forma extraña de vez en cuando, se abre el depurador para buscar la causa y el error desaparece como por arte de magia. Basta con añadir una línea que imprima un mensaje de comprobación para que el problema deje de aparecer, y al quitarla puede volver. Los desarrolladores tomaron prestado el nombre de un físico para bautizar a los bugs que se esconden justo cuando intentan examinarlos. Así surgió el apodo «Heisenbug».

En pocas palabras, un Heisenbug es un fallo de software que desaparece o cambia de comportamiento cuando se intenta investigar su causa. El término alude al efecto del observador, según el cual el propio acto de observar cambia el estado de lo observado, y se usa para designar fallos especialmente difíciles de reproducir y rastrear.

En este artículo veremos, por orden, de dónde viene el nombre Heisenbug, por qué se esconde el fallo, qué otros apodos se usan junto con este y cómo atrapar un Heisenbug.


El bug que se esconde cuando intentas observarlo, el Heisenbug

Origen del nombre Heisenbug

Un microscopio de latón y un portátil de última generación, uno al lado del otro sobre un escritorio de madera en un aula antigua con una pizarra en blanco

Este apodo nació de la combinación de un conocido principio de la física y una broma de programadores.

(1) Un juego de palabras con el nombre de un físico
Heisenbug es un juego de palabras que combina el apellido del físico alemán Werner Heisenberg, quien formuló el principio de incertidumbre, con bug, que en inglés significa «bicho». El juego de palabras busca evocar el efecto del observador, por el cual lo observado cambia en el momento en que se intenta observarlo.

(2) Primera aparición documentada
La referencia más antigua que se conoce figura en una publicación de la Asociación de Maquinaria Computacional de Estados Unidos (ACM) de 1983. En 1985, el investigador de bases de datos Jim Gray usó el término en un artículo sobre fallos de software, por lo que a veces se le atribuyó erróneamente su creación.

(3) Un antecedente en la electrónica
En electrónica ya se usaba la expresión «efecto de sonda» (probe effect) para un fenómeno similar. El simple hecho de poner una sonda de medición en contacto con un circuito altera el funcionamiento del dispositivo.

El nombre también ha recibido críticas. Se señala que el principio de incertidumbre y el efecto del observador son conceptos distintos y que el apodo los mezcla como si fueran uno solo. Por eso conviene entender Heisenbug como una expresión ingeniosa de la jerga de los desarrolladores, más que como un término científico preciso.


¿Por qué se esconde un Heisenbug?

Dos monitores muestran bloques de colores difusos en el escritorio de un desarrollador por la noche, junto a un teclado, un patito de goma y una taza de té

El fallo no está realmente pendiente de si alguien lo observa. Lo que ocurre es que las herramientas y los métodos que se usan para investigar su causa modifican ligeramente las condiciones de ejecución del programa.

(1) Cambian los tiempos de ejecución
Al ejecutar el programa línea por línea con un depurador, este funciona mucho más despacio de lo habitual. En los programas que ejecutan varias tareas simultáneamente son frecuentes las condiciones de carrera (race condition), que pueden surgir con solo una pequeña alteración en el orden de las tareas. Si cambia la velocidad, puede que esa alteración no se produzca.

(2) Cambia la disposición de la memoria
Añadir una instrucción que imprima un mensaje de comprobación o volver a compilar el programa para depurarlo cambia la ubicación de las variables en la memoria. Si la causa es una variable sin inicializar o un puntero que apunta a una ubicación incorrecta, el síntoma cambia en cuanto cambia esa ubicación.

(3) Se activa o se desactiva la optimización
Es frecuente que el error solo aparezca en un programa optimizado para mejorar el rendimiento y que el programa funcione con normalidad al desactivar la optimización para depurarlo. Por ejemplo, la precisión de un resultado puede variar según se mantenga en un registro o se traslade a la memoria, lo que puede cambiar el resultado de una comparación entre números de punto flotante.

En definitiva, un Heisenbug es la manifestación de un defecto real subyacente que se hace visible o se oculta según las condiciones de ejecución. La causa puede seguir presente aunque el síntoma desaparezca.

Infografía que explica por qué se esconde un Heisenbug. Las flechas muestran cómo el uso de un depurador o de instrucciones de salida para investigar la causa cambia las condiciones de ejecución, como los tiempos de ejecución, la disposición de la memoria y si la optimización está activada. Esos cambios hacen que los síntomas desaparezcan o se manifiesten de otra manera. En la parte inferior, una advertencia indica que el defecto persiste aunque desaparezcan los síntomas.
Un Heisenbug es un fallo cuyos síntomas desaparecen o cambian cuando la herramienta que se usa para examinarlo altera las condiciones de ejecución. La imagen es un ejemplo simplificado para facilitar la comprensión. La causa real puede variar de un programa a otro, como una condición de carrera, una variable sin inicializar o un puntero incorrecto.

Otros apodos de bugs que se usan junto con Heisenbug

Primer plano de un pequeño adorno metálico con forma de escarabajo sobre una placa de circuito verde

A medida que se popularizó el término Heisenbug, surgieron varios apodos de bugs que tomaban prestados nombres de científicos.

  • Bohrbug. Al igual que el modelo atómico del físico Niels Bohr, este bug sigue reglas fijas y se manifiesta siempre de la misma manera en las mismas condiciones. Como es fácil de reproducir, resulta relativamente fácil de detectar.
  • Mandelbug. Es un bug cuya causa es tan compleja que su comportamiento parece caótico. Su nombre proviene del matemático Benoît Mandelbrot, que estudió los fractales.
  • Schrödinbug. Es un bug que empieza a causar problemas reales después de que un desarrollador, al leer el código, se da cuenta de que ese código jamás podría haber funcionado.
  • Higgs-bugson. Es un bug que, a juzgar por los registros y los avisos de los usuarios, parece existir con toda claridad, pero que resulta difícil de reproducir en el entorno de desarrollo.

La mayoría de estos apodos nacieron como bromas, pero sirven para distinguir de forma concisa los fallos según si se pueden reproducir y cuán compleja es su causa.


Cómo atrapar un Heisenbug

Una escena tranquila con una lupa sobre el teclado de un portátil y, al lado, un cuaderno abierto en blanco y un bolígrafo

Un Heisenbug es difícil de atrapar, pero se puede conseguir si se cambia de enfoque.

(1) Registrar lo que ocurre sin detener la ejecución
Conviene generar registros ligeros que apenas alteren el flujo de ejecución y revisarlos después de que ocurra el fallo, en vez de detener el programa con un depurador. El primer principio es reducir el impacto de la observación.

(2) Recrear las mismas condiciones
Hay que reproducir con la mayor fidelidad posible la configuración de compilación, los valores de entrada y el entorno de ejecución en los que se produjo el fallo. También se pueden usar herramientas que graban la ejecución y permiten reproducirla luego tal como ocurrió.

(3) Acotar las posibles causas
Conviene revisar una por una las causas que suelen provocar Heisenbugs, como las variables sin inicializar, los punteros incorrectos y los problemas en el orden de ejecución de las tareas. Las herramientas de análisis de código y de comprobación de memoria facilitan mucho este proceso.

(4) Seguir investigando cuando desaparece el síntoma
Si el síntoma deja de aparecer al cambiar una línea de código, hay que comprobar si el bug se ha corregido o si solo se ha escondido temporalmente. Solo cuando se puede explicar la causa cabe decir que el problema está resuelto.


Los Heisenbugs recuerdan a los desarrolladores que hasta las herramientas de observación forman parte del sistema. Incluso cuando el fallo deja de verse, hay que preguntarse qué han cambiado las condiciones de ejecución.

El primer paso para desarrollar software fiable es seguir investigando hasta entender por qué desapareció el síntoma, sin conformarse con que haya dejado de aparecer.

Guarda este artículo en PDF

Compra la edición en el idioma que has seleccionado del artículo que estás leyendo.

US$1.00
Idioma seleccionado: Español

US$1.00 · 1 artículo · 1 idioma

Una vez realizada la compra, puedes volver a descargar la edición que compraste iniciando sesión con la misma cuenta.

Ver una muestra del PDF ↗Puedes leer el artículo completo gratis. La muestra te permite ver la tipografía y la estructura del archivo.