GDB tiene una nueva versión que admite la depuración inversa (consulte http://www.gnu.org/software/gdb/news/reversible.html ). Llegué a preguntarme cómo funciona eso.
Para que la depuración inversa funcione, me parece que debe almacenar todo el estado de la máquina, incluida la memoria para cada paso. Esto haría que el rendimiento fuera increíblemente lento, sin mencionar el uso de mucha memoria. ¿Cómo se resuelven estos problemas?
reverse-debugging
Nathan Fellman
fuente
fuente
Respuestas:
Soy un mantenedor de gdb y uno de los autores de la nueva depuración inversa. Me encantaría hablar sobre cómo funciona. Como varias personas han especulado, debe guardar suficiente estado de la máquina para poder restaurarlo más tarde. Hay varios esquemas, uno de los cuales es simplemente guardar los registros o ubicaciones de memoria que son modificados por cada instrucción de máquina. Luego, para "deshacer" esa instrucción, simplemente revierte los datos en esos registros o ubicaciones de memoria.
Sí, es caro, pero las CPU modernas son tan rápidas que, de todos modos, cuando eres interactivo (haciendo pasos o puntos de interrupción), no lo notas mucho.
fuente
next
ystep
comandos que ha escrito, o permite deshacer cualquier número de instrucciones? Por ejemplo, si establezco un punto de interrupción en una instrucción y dejo que se ejecute hasta entonces, ¿puedo volver a la instrucción anterior, aunque la haya omitido?Tenga en cuenta que no debe olvidar el uso de simuladores, máquinas virtuales y grabadores de hardware para implementar la ejecución inversa.
Otra solución para implementarlo es rastrear la ejecución en hardware físico, como lo hacen GreenHills y Lauterbach en sus depuradores basados en hardware. Con base en este seguimiento fijo de la acción de cada instrucción, puede moverse a cualquier punto del seguimiento eliminando los efectos de cada instrucción por turno. Tenga en cuenta que esto supone que puede rastrear todas las cosas que afectan el estado visible en el depurador.
Otra forma es usar un método de punto de control + re-ejecución, que es usado por VmWare Workstation 6.5 y Virtutech Simics 3.0 (y posterior), y que parece venir con Visual Studio 2010. Aquí, usa una máquina virtual o un simulador para obtener un nivel de indirección en la ejecución de un sistema. Regularmente vuelca todo el estado en el disco o la memoria, y luego confía en que el simulador pueda volver a ejecutar de manera determinista la misma ruta exacta del programa.
Simplificado, funciona así: digamos que se encuentra en el momento T en la ejecución de un sistema. Para ir al tiempo T-1, toma algún punto de control del punto t <T, y luego ejecuta ciclos (Tt-1) para terminar un ciclo antes de donde estaba. Se puede hacer que esto funcione muy bien y se aplique incluso a cargas de trabajo que realizan E / S de disco, constan de código a nivel de kernel y realizan el trabajo del controlador de dispositivo. La clave es tener un simulador que contenga todo el sistema de destino, con todos sus procesadores, dispositivos, memorias e IO. Consulte la lista de correo de gdb y la discusión que sigue en la lista de correo de gdb para obtener más detalles. Yo mismo utilizo este enfoque con bastante frecuencia para depurar códigos complicados, especialmente en los controladores de dispositivos y los primeros arranques del sistema operativo.
Otra fuente de información es un documento técnico de Virtutech sobre puntos de control (que escribí, en forma completa).
fuente
Durante una sesión de EclipseCon, también les preguntamos cómo hacen esto con Chronon Debugger para Java. Ese no le permite dar un paso atrás, pero puede reproducir la ejecución de un programa grabado de tal manera que se siente como una depuración inversa. (La principal diferencia es que no puede cambiar el programa en ejecución en el depurador Chronon, mientras que puede hacerlo en la mayoría de los demás depuradores de Java).
Si lo entendí correctamente, manipula el código de bytes del programa en ejecución, de modo que se registra cada cambio de un estado interno del programa. Los estados externos no necesitan registrarse adicionalmente. Si influyen en su programa de alguna manera, entonces debe tener una variable interna que coincida con ese estado externo (y por lo tanto, esa variable interna es suficiente).
Durante el tiempo de reproducción, básicamente pueden recrear todos los estados del programa en ejecución a partir de los cambios de estado registrados.
Curiosamente, los cambios de estado son mucho más pequeños de lo que cabría esperar a primera vista. Entonces, si tiene una instrucción "if" condicional, pensaría que necesita al menos un bit para registrar si el programa tomó la instrucción then o la instrucción else. En muchos casos puede evitar incluso eso, como en el caso de que esas diferentes ramas contengan un valor de retorno. Entonces es suficiente registrar solo el valor de retorno (que sería necesario de todos modos) y volver a calcular la decisión sobre la rama ejecutada a partir del valor de retorno en sí.
fuente
Aunque esta pregunta es antigua, la mayoría de las respuestas también lo son, y como depuración inversasigue siendo un tema interesante, estoy publicando una respuesta de 2015. Los capítulos 1 y 2 de mi tesis de maestría, Combinando la depuración inversa y la programación en vivo hacia el pensamiento visual en la programación de computadoras , cubre algunos de los enfoques históricos para la depuración inversa (especialmente enfocados en el enfoque de instantánea (o punto de control) y reproducción), y explica la diferencia entre él y la depuración omnisciente:
fuente
mozilla
rr
es una alternativa más sólida a la depuración inversa de GDBhttps://github.com/mozilla/rr
El registro y la reproducción integrados de GDB tienen graves limitaciones, por ejemplo, no admite instrucciones AVX: la depuración inversa de gdb falla con "El registro del proceso no admite la instrucción 0xf0d en la dirección"
Ventajas de rr:
rr logra esto ejecutando primero el programa de una manera que registre lo que sucedió en cada evento no determinista, como un cambio de hilo.
Luego, durante la segunda ejecución de repetición, utiliza ese archivo de seguimiento, que es sorprendentemente pequeño, para reconstruir exactamente lo que sucedió en la ejecución no determinista original pero de una manera determinista, ya sea hacia adelante o hacia atrás.
rr fue desarrollado originalmente por Mozilla para ayudarlos a reproducir errores de sincronización que aparecieron en sus pruebas nocturnas al día siguiente. Pero el aspecto de la depuración inversa también es fundamental para cuando tiene un error que solo ocurre horas dentro de la ejecución, ya que a menudo desea dar un paso atrás para examinar qué estado anterior condujo al error posterior.
El siguiente ejemplo muestra algunas de sus características, en particular los
reverse-next
,reverse-step
yreverse-continue
los comandos.Instalar en Ubuntu 18.04:
Programa de prueba:
compilar y ejecutar:
Ahora está dentro de una sesión de GDB y puede revertir correctamente la depuración:
Al depurar software complejo, es probable que corra hasta un punto de caída y luego caiga dentro de un marco profundo. En ese caso, no olvide que
reverse-next
en marcos superiores, primero debe:hasta ese marco, hacer lo habitual
up
no es suficiente.Las limitaciones más graves de rr en mi opinión son:
UndoDB es una alternativa comercial a rr: https://undo.io Ambos están basados en rastreo / reproducción, pero no estoy seguro de cómo se comparan en términos de características y rendimiento.
fuente
Nathan Fellman escribió:
Puede deshacer cualquier cantidad de instrucciones. No está restringido, por ejemplo, a detenerse solo en los puntos donde se detuvo cuando estaba avanzando. Puede establecer un nuevo punto de interrupción y ejecutarlo hacia atrás.
Si. Siempre que haya activado el modo de grabación antes de llegar al punto de interrupción.
fuente
Aquí es cómo otro inversa depurador llamado ODB funciona. Extraer:
Supongo que el gdb uno funciona de la misma manera.
fuente
La depuración inversa significa que puede ejecutar el programa hacia atrás, lo cual es muy útil para rastrear la causa de un problema.
No es necesario almacenar el estado completo de la máquina para cada paso, solo los cambios. Probablemente todavía sea bastante caro.
fuente