2009-09-24 13 views
69

GDB tiene una nueva versión que admite la depuración inversa (consulte http://www.gnu.org/software/gdb/news/reversible.html). Me pregunto cómo funciona eso.¿Cómo funciona la depuración inversa?

Para que la depuración inversa funcione, me parece que necesita almacenar todo el estado de la máquina, incluida la memoria de cada paso. Esto haría que el rendimiento sea increíblemente lento, por no mencionar el uso de mucha memoria. ¿Cómo se resuelven estos problemas?

+3

Me imagino que podría llegar a funcionar con el almacenamiento de los deltas de estado en lugar de todo el estado, pero todavía parece que podría ser costoso. – spender

+1

pregunta relacionada http://stackoverflow.com/questions/522619/bidirectional-or-reverse-debugging –

+0

Guardar deltas puede funcionar muy bien, y es realmente necesario para una solución eficaz de sistema completo reversible. – jakobengblom2

Respuesta

109

Soy un mantenedor de gdb y uno de los autores de la nueva depuración inversa. Estaría feliz de hablar sobre cómo funciona. Como varias personas han especulado, debe guardar suficiente estado de la máquina que pueda restaurar más tarde. Hay una serie de esquemas, uno de los cuales es simplemente guardar los registros o las ubicaciones de memoria que se modifican con cada instrucción de máquina. Luego, para "deshacer" esa instrucción, solo revierte los datos en esos registros o ubicaciones de memoria.

Sí, es caro, pero las CPU modernas son tan rápidas que cuando se es interactivo de todos modos (haciendo pasos o puntos de interrupción), realmente no se nota tanto.

+3

Pero, ¿la depuración inversa solo le permite revertir los comandos 'siguiente' y' paso' que escribió, o le permite deshacer cualquier cantidad de instrucciones? Por ejemplo, si configuro un punto de interrupción en una instrucción y la dejo funcionar hasta entonces, ¿puedo volver a la instrucción anterior, aunque me salté sobre ella? –

+9

> Pero la depuración inversa solo le permite revertir los comandos del próximo y el paso que escribió o le permite deshacer cualquier cantidad de instrucciones Puede deshacer cualquier cantidad de instrucciones. No estás restringido, por ejemplo, solo parando en los puntos donde te detuviste cuando avanzaste. Puede establecer un nuevo punto de interrupción y ejecutarlo hacia atrás > Por ejemplo, si configuro un punto de interrupción en una instrucción y la dejo funcionar hasta entonces, ¿puedo retroceder a la instrucción anterior, aunque me salté sobre ella Sí Siempre y cuando haya activado el modo de grabación antes de ejecutar el punto de interrupción –

+2

Disculpe por el texto sin formato, no sé qué pasa con eso. –

2

Here es como funciona otro depurador inverso llamado ODB. Extracto:

Omnisciente La depuración es la idea de recoger "las marcas de tiempo" en cada "punto de interés" (ajuste de un valor, hacer una llamada a un método, de lanzamiento/captura una excepción) en un programa de y luego permitir que el programador use esas marcas de tiempo en explore el historial de ese programa ejecución.

El ODB ... inserta código en las clases del programa como que se cargan y cuando el programa se ejecuta , los eventos se registran.

Supongo que el gdb funciona del mismo modo.

+0

¿Esto requeriría directivas en el código para decirle al compilador y al depurador dónde están esos puntos interesantes? –

+0

No. Hay una demostración de Java Web Start en www.LambdaCS.com/debugger/debugger.html que le muestra cómo funciona. Parece un programa normal. Eso es ODB de todos modos, no sé sobre gdb. Aunque es genial :) – demoncodemonkey

+0

Tenga en cuenta que la solución gdb NO cambia el programa objetivo de ninguna manera. Si tiene que instrumentar un programa para depurarlo, tiene muchas posibilidades de que el problema desaparezca debido a la diferencia de tiempo y otras perturbaciones. Todas las herramientas comerciales de revexec se basan en algún tipo de registro externo que no cambia el código del programa en sí. – jakobengblom2

2

La depuración inversa significa que puede ejecutar el programa hacia atrás, lo que es muy útil para rastrear la causa de un problema.

No necesita almacenar el estado completo de la máquina para cada paso, solo los cambios. Es probable que todavía sea bastante caro.

+0

Veo, pero aún necesita interrumpir la ejecución en cada cambio para guardar los cambios. –

+0

Sí, es correcto, pero las máquinas ahora son bastante rápidas, y en términos humanos no creo que la desaceleración sea insoportable. Es comparable a valgrind, tal vez no tan lento como valgrind. –

3

Nathan Fellman escribió:

Pero es reversible depuración únicamente permitirá revertir el próximo paso y los comandos que ha escrito, o se permitirá deshacer cualquier número de instrucciones?

Puede deshacer cualquier cantidad de instrucciones. No está restringido, por ejemplo, al y solo se detiene en los puntos donde se detuvo cuando estaba avanzando. Puede establecer un nuevo punto de interrupción y ejecutarlo hacia atrás.

Por ejemplo, si configuro un punto de interrupción en una instrucción y la dejo funcionar hasta entonces, ¿puedo volver a la instrucción anterior, aunque me salté sobre ella?

Sí. Siempre y cuando haya activado el modo de grabación antes de ejecutar el punto de interrupción.

+2

Una parte crucial de cualquier solución inversa es que la encienda en algún momento y solo pueda retroceder hasta ese punto. No hay magia que pueda hacer funcionar una máquina en verdadero reverso y descubrir lo que sucedió anteriormente sin algún tipo de registro de lo sucedido. – jakobengblom2

10

Tenga en cuenta que no debe olvidar el uso de simuladores, máquinas virtuales y grabadoras 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. En función de este rastro fijo de la acción de cada instrucción, puede moverse a cualquier punto de la traza eliminando los efectos de cada instrucción sucesivamente. Tenga en cuenta que esto supone que puede rastrear todas las cosas que afectan el estado visible en el depurador.

Otra forma es utilizar un método de punto de control + re-ejecución, que VmWare Workstation 6.5 y Virtutech Simics 3.0 (y posterior) utilizan, y que parece venir con Visual Studio 2010. Aquí, utiliza un virtual máquina o un simulador para obtener un nivel de indirección en la ejecución de un sistema. Usted regularmente descarga todo el estado en el disco o la memoria, y luego confía en que el simulador pueda volver a ejecutar determinísticamente la misma ruta del programa.

Simplificado, funciona de esta manera: supongamos que está en el momento T en la ejecución de un sistema. Para ir al tiempo T-1, toma un punto de control del punto t < T, y luego ejecuta (T-t-1) ciclos para terminar un ciclo antes de donde estabas. Esto se puede hacer para que funcione muy bien, y se aplique incluso para cargas de trabajo que hacen IO de disco, consisten en código de nivel de núcleo 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 the gdb mailinglist y la discusión siguiente en la lista de distribución de gdb para obtener más detalles. Utilizo este enfoque con bastante regularidad para depurar código engañoso, especialmente en los controladores de dispositivos y las primeras botas del sistema operativo.

Otra fuente de información es un Virtutech white paper on checkpointing (que escribí, en la revelación completa).

+0

También vea http://jakob.engbloms.se/archives/1547 y sus dos siguientes entradas de blog para un recorrido más completo de las técnicas de depuración inversa. – jakobengblom2

+0

¿Qué tal la capacidad de "establecer puntos de guardado" en lugar de implementar pasos inversos? Por lo tanto, debe depurar y, en algún momento, puede seleccionar el paso actual como "punto de guardado", y más adelante podrá regresar a ese punto de guardado y volver a avanzar, editando sus variables si es necesario. Algo así como "instantáneas" para máquinas virtuales o "puntos de restauración" para sistemas operativos. – Rolf

7

Durante una sesión de EclipseCon también preguntamos cómo lo hacen con el Chronon Debugger para Java. Eso no le permite realmente dar un paso atrás, pero puede reproducir una ejecución de programa grabada de tal manera que siente como la depuración inversa. (La principal diferencia es que no puede cambiar el programa en ejecución en el depurador Chronon, aunque puede hacerlo en la mayoría de los otros depuradores de Java).

Si lo entendí correctamente, manipula el código de bytes del programa en ejecución, tal que cada cambio de un estado interno del programa se registra. 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, pueden básicamente recrear cada estado del programa en ejecución desde los cambios de estado grabados.

Curiosamente, los cambios de estado son mucho más pequeños de lo que cabría esperar a primera vista. Por lo tanto, si tiene una declaración condicional "si", pensaría que necesita al menos un bit para registrar si el programa tomó la instrucción then- o the 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 de todos modos sería necesario) y recalcular la decisión sobre la bifurcación ejecutada a partir del valor de retorno.

6

Aunque esta pregunta es antigua, la mayoría de las respuestas también lo son, y como sigue siendo un tema interesante, publicaré una respuesta de 2015. Los capítulos 1 y 2 de mi tesis de maestría, Combining reverse debugging and live programming towards visual thinking in computer programming, 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 repetición), y explica la diferencia entre él y la depuración omnisciente:

La computadora, después de haber ejecutado el programa hasta cierto punto, realmente debería ser capaz de proporcionarnos información al respecto. Tal mejora es posible, y se encuentra en lo que se llaman depuradores omniscientes. Generalmente se clasifican como depuradores inversos, aunque podrían describirse con mayor precisión como depuradores de "registro de historial", ya que simplemente registran la información durante la ejecución para verla o consultarla más tarde, en lugar de permitir al programador retroceder en el tiempo en un programa en ejecución . "Omnisciente" proviene del hecho de que toda la historia del estado del programa, una vez registrada, está disponible para el depurador después de la ejecución. Entonces no hay necesidad de volver a ejecutar el programa, y ​​no hay necesidad de instrumentación de código manual.

La depuración omnisciente basada en software comenzó con el sistema EXDAMS 1969 donde se llamó "reproducción de historial de tiempo de depuración". El depurador de GNU, GDB, ha soportado la depuración omnisciente desde 2009, con su función 'grabar y reproducir el proceso'. TotalView, UndoDB y Chronon parecen ser los mejores depuradores omniscientes actualmente disponibles, pero son sistemas comerciales. TOD, para Java, parece ser la mejor alternativa de código abierto, que hace uso de la reproducción determinista parcial, así como la captura parcial de trazas y una base de datos distribuida para permitir el registro de los grandes volúmenes de información involucrados.

También existen depuradores que no solo permiten la navegación de una grabación, sino que también pueden retroceder en el tiempo de ejecución. Se pueden describir con más precisión como depuradores de retroceso en el tiempo, de viaje en el tiempo, bidireccionales o inversos.

El primer sistema de este tipo fue el prototipo de 1981 COPE ...