sentencia resueltos programas programa principiantes para ejercicios ejemplos comandos c++ gdb expression

resueltos - programa en c++



¿Cómo evalúa GDB las expresiones de C++ en tiempo de ejecución? (2)

lo que me permite escribir cosas como print v.at (4);

gdb puede llamar a funciones compiladas en el binario. Esto es exactamente lo que sucede aquí. gdb llama a std::vector member function at() e imprime el resultado por usted, consulte la documentación .

También tenga en cuenta que esto es posible porque está usando v.at(0) en su código. Si elimina esta parte del código, v.at() no se creará una instancia y no estará disponible en el binario resultante para que gdb no pueda invocarlo.

Al depurar, hace poco noté que GDB tiene la capacidad de evaluar expresiones "complejas" mientras depura un programa, y ​​me pregunto cómo lo hace. Por ejemplo, con el siguiente código:

int main() { std::vector<int> v = {1, 2, 3}; int k = 0; std::cin >> k; v.push_back(k); return v.at(0); }

Puedo compilar el programa g++ -g myprogram.cpp y depurarlo en GDB, lo que me permite escribir cosas como print v.at(4); (que imprime el valor correcto después de que k se ingresa dinámicamente) e print v.at(2) == 3 que se evalúa como verdadero.

Me pregunto cómo GDB hace esto. Esta pregunta ASTRA insinúa que es algo "compilado en la memoria", pero no da más detalles, así que me pregunto si utiliza algún tipo de JIT para hacer que todo funcione o algo más. ¿Están compilando el código en línea mientras lo escribo y lo ejecuto? ¿Tienen un marco para evaluar C ++ sobre la marcha en el contexto de depuración? En esencia, quiero reproducir esto en un depurador que estoy escribiendo para evaluar expresiones en puntos de interrupción, por lo que tengo curiosidad de cómo lo hace GDB.


Respuesta corta: no compila el código.

Respuesta larga:

  1. Usted llama al comando print y el procedimiento ocurre en printcmd.c
  2. Llama a evaluate_expression , definida en eval.c , que evalúa una expresión leyendo la memoria objetivo y calculándola dentro de gdb para operadores estándar, de lo contrario use call_function_by_hand .
  3. call_function_by_hand se define en infcall.c . Cuando se llama, el procedimiento detiene la ejecución del objetivo (a veces no, por lo que es posible bloquear un programa multiproceso con esta función).
  4. Inyectar código en el programa que se está depurando.
  5. Recupere el resultado leyendo la memoria y, si es necesario, préstelo.

Puede enfocarse en el código de call_function_by_hand para una mejor comprensión.

Nota: compile es una cosa diferente de print / call .

Respuesta completa:

En unos días, puedo escribir un análisis detallado de cómo GDB implementa esta función, para una lectura posterior.