c++ - Editar y continuar en GDB
g++ (3)
Es una cantidad de trabajo sorprendentemente no trivial, que abarca muchas decisiones de diseño y compensaciones de características. Considera: estás depurando. El debugee está suspendido. Su imagen en la memoria contiene el código de objeto de la fuente y el diseño binario de los objetos, el montón, las pilas. El depurador está inspeccionando su imagen de memoria. Ha cargado información de depuración sobre los símbolos, tipos, asignaciones de direcciones, pc (ip) a las correspondencias de origen. Muestra la pila de llamadas, valores de datos.
Ahora desea permitir un conjunto particular de posibles ediciones en el código y / o los datos, sin detener el debuggee y reiniciar. Lo más simple podría ser cambiar una línea de código a otra. Tal vez usted recompile ese archivo o solo esa función o solo esa línea. Ahora tienes que parchear la imagen de depuración para ejecutar esa nueva línea de código la próxima vez que la pases o la ejecutes. ¿Cómo funciona eso bajo el capó? ¿Qué sucede si el código es más grande que la línea de código que reemplazó? ¿Cómo interactúa con las optimizaciones del compilador? Quizás solo pueda hacer esto en un destino de depuración de EnC especialmente compilado. Tal vez usted limitará los sitios posibles, es legal para EnC. Considere: qué sucede si edita una línea de código en una función suspendida en la pila de llamadas. Cuando el código vuelve, ¿se ejecuta la versión original de la función o la versión con su línea modificada? Si la versión original, ¿de dónde viene esa fuente?
¿Se puede agregar o eliminar los locales? ¿Qué le hace eso a la pila de llamadas de marcos suspendidos? ¿De la función actual?
¿Se pueden cambiar las firmas de función? ¿Agregar campos a / eliminar campos de objetos? ¿Qué pasa con las instancias existentes? ¿Qué pasa con los destructores pendientes o finalizadores? Etc.
Hay muchos, muchos detalles de funcionalidad a los que hay que prestar atención para hacer que cualquier tipo de EnC funcione. Luego hay muchos problemas de integración de herramientas cruzadas necesarios para proporcionar la infraestructura para alimentar a EnC. En particular, es útil tener algún tipo de repositorio de información de depuración que pueda poner a disposición del depurador la información de depuración anterior y posterior y el código objeto. Para C ++, la información de depuración incrementable y actualizable en los PDB ayuda. La vinculación incremental puede ayudar también.
Mirando desde el ecosistema de la EM al ecosistema del CCG, es fácil imaginar los problemas de complejidad e integración a través de GDB / GCC / binutils, la gran cantidad de objetivos, algunos abstracciones de objetivos específicos de EnC necesarios y la naturaleza "agradable de tener pero no esencial". de EnC, son las razones por las que aún no ha aparecido en GDB / GCC.
¡Feliz piratería!
(ps. Es instructivo e inspirador ver lo que podría hacer el entorno de programación interactivo Smalltalk-80. En St80 no existía el concepto de "reinicio": la imagen y su memoria de objetos estaban siempre activas, si editaba algún aspecto de un clase que todavía tenía que seguir ejecutando. En tales entornos, el control de versiones de los objetos no era hipotético.)
Sé que E&C es un tema controvertido y algunos dicen que fomenta un enfoque incorrecto para la depuración, pero aún así, creo que podemos estar de acuerdo en que hay numerosos casos en los que es claramente útil: experimentar con diferentes valores de algunas constantes y rediseñar los parámetros de la GUI sobre la marcha para encontrar un buen aspecto ... lo que sea.
Mi pregunta es: ¿Alguna vez vamos a tener E&C en GDB? Entiendo que es una característica específica de la plataforma y necesita una colaboración seria con el compilador, el depurador y el sistema operativo (MSVC lo tiene fácil, ya que el compilador y el depurador siempre vienen en un paquete) , pero ... realizable. Incluso escuché algo acerca de que Apple lo implementó en su versión de GCC [cita requerida] . Y diría que sí es factible.
Conociendo todo el bombo sobre la E&C de MSVC (mi experiencia dice que es lo primero que mencionan los usuarios de MSVC cuando se les pregunta "por qué no cambiar a Eclipse y gcc / gdb" ), me sorprende seriamente que, después de algunos años, GCC / GDB todavía no lo haga. tener tal característica ¿Hay buenas razones para eso? ¿Hay alguien trabajando en ello mientras hablamos?
Esta es una referencia bastante buena a la antigua implementación de Apple de "corregir y continuar". También hace referencia a otras implementaciones de trabajo.
http://sources.redhat.com/ml/gdb/2003-06/msg00500.html
Aquí hay un fragmento de código:
Reparar y continuar es una característica implementada por muchos otros depuradores, que agregamos a nuestro gdb para esta versión. Sun Workshop, SGI ProDev WorkShop, Visual Studio de Microsoft, wdb de HP y Hotspot Java VM de Sun ofrecen esta característica de una forma u otra. Basé nuestra implementación en la característica HP wdb Fix and Continue, que agregaron hace algunos años. Aunque mi implementación final sigue los lineamientos generales del enfoque que adoptaron, casi no hay código compartido entre ellos. Algo de esto se debe a las diferencias arquitectónicas (tanto el procesador como el ABI), pero aún más se debe a las diferencias de diseño de la implementación.
Tenga en cuenta que esta capacidad puede haberse eliminado en una versión posterior de su cadena de herramientas.
ACTUALIZACIÓN: 21-dic-2012 Hay una presentación en PDF de la Hoja de ruta de GDB que incluye una diapositiva que describe "Reparar y continuar" entre otros puntos. La presentación tiene fecha del 9 de julio de 2012, por lo que tal vez haya esperanza de agregar esto en algún momento. La presentación fue parte del GNU Tools Cauldron 2012 .
No estoy familiarizado con la E&C de MSVC, pero GDB tiene algunas de las cosas que mencionó:
http://sourceware.org/gdb/current/onlinedocs/gdb/Altering.html#Altering
17. Alterar la ejecución
Una vez que crea que ha encontrado un error en su programa, es posible que desee saber con certeza si corregir el error aparente podría llevar a resultados correctos en el resto de la ejecución. Puede encontrar la respuesta por experimento, utilizando las funciones de gdb para alterar la ejecución del programa.
Por ejemplo, puede almacenar nuevos valores en variables o ubicaciones de memoria, dar una señal al programa, reiniciarlo en una dirección diferente o incluso regresar prematuramente de una función.
Asignación : Asignación a variables
Salto : Continuando en una dirección diferente.
Señalización : dando a su programa una señal.
Regresando : Regresando de una función
Llamando : Llamando a las funciones de tu programa
Parches : parcheando tu programa
Compilación e inyección de código : Compilación e inyección de código en GDB