programación - ¿Cómo funcionan los puntos de interrupción en el código C++?
programacion msp430 (4)
AFAIK todos los depuradores (para cualquier lenguaje compilado) que permiten un número ilimitado de puntos de interrupción utilizan una variante de reemplazar la instrucción para ser breakpoint con un valor especial (como se describe anteriormente) y mantener una lista de lugares donde se han colocado estos valores.
Cuando el procesador intenta ejecutar uno de estos valores especiales, se genera una excepción, el depurador lo detecta y comprueba si la dirección de la excepción se encuentra en su lista de puntos de interrupción. Si es así, se invoca el depurador y se le da al usuario la oportunidad de interactuar. Si no lo es, entonces la excepción se debe a algo que estaba en el programa desde el principio y el depurador permite que la excepción ''pase'' a cualquier controlador de errores que pueda existir.
Tenga en cuenta también, que el código de auto-modificación de depuración puede fallar precisamente porque el depurador modifica momentáneamente el código en sí. (Por supuesto, nadie escribiría auto modificante, ¿verdad?> ;-)
Por estas razones, es importante que el depurador tenga la oportunidad de eliminar todos los puntos de interrupción que establece antes de finalizar la sesión de depuración.
¿Cómo funcionan los puntos de interrupción en el código C ++? ¿Se insertan instrucciones especiales entre algunas instrucciones del ensamblador cuando se compila el código? ¿O hay algo más en su lugar? Además, ¿cómo se implementa el paso a través del código? De la misma manera que los puntos de interrupción ...?
De acuerdo con esta entrada del blog en technochakra.com tienes razón:
Los puntos de interrupción del software funcionan insertando una instrucción especial en el programa que se está depurando. Esta instrucción especial en la plataforma Intel es "int 3". Cuando se ejecuta, llama al controlador de excepción del depurador.
Sin embargo, no estoy seguro de cómo implementar la próxima instrucción. Sin embargo, el artículo continúa agregando:
Por razones prácticas, no es aconsejable solicitar una recompilación cada vez que se agrega o elimina un punto de interrupción. Los depuradores cambian la imagen cargada del ejecutable en la memoria e insertan la instrucción "int 3" en el tiempo de ejecución.
Sin embargo, esto solo se usaría para la opción "ejecutar a la línea actual".
El paso único se implementa en el nivel de código (ensamblador) no en el nivel C ++. El depurador sabe cómo asignar las líneas de código de C ++ a las direcciones de código.
Hay diferentes implementaciones. Hay CPU que soportan la depuración con registros de punto de interrupción. Cuando la ejecución alcanza la dirección en el registro de punto de interrupción, la CPU ejecuta una excepción de punto de interrupción.
Un enfoque diferente es parchear el código para el momento de la ejecución con una instrucción especial, en el mejor de una instrucción de un byte. En sistemas x86 que generalmente int 3.
El primer enfoque permite puntos de interrupción en ROM, el segundo permite más puntos de interrupción al mismo tiempo.
Esto depende mucho de la CPU y el depurador.
Por ejemplo, una de las posibles soluciones en la CPU x86:
- Insertar instrucción INT3 de un byte en el lugar requerido
- Espere hasta que llegue la excepción del punto de interrupción
- Compare la dirección de excepción con la lista de puntos de interrupción para determinar cuál
- Hacer acciones de punto de interrupción
- Reemplace INT3 con el byte original y cambie el proceso depurado al modo de seguimiento (ejecución paso a paso de las instrucciones de la CPU)
- Continuar proceso depurado
- Inmediatamente se detecta una excepción de rastreo: se ejecutó la instrucción
- Poner INT3 de vuelta
Los puntos de vigilancia se pueden implementar de la misma manera, pero en lugar de INT3 se coloca la página de memoria donde la variable observada está en solo lectura, o en modo sin acceso, y se espera la excepción de segmentación.
El paso a través del ensamblaje también se puede hacer utilizando el modo de rastreo. Pasar por las líneas de origen también se puede hacer colocando puntos de interrupción en las siguientes instrucciones, en función de los datos de depuración.
Además, algunas CPU tienen soporte de punto de interrupción de hardware, cuando simplemente carga la dirección en algún registro.