En el post anterior introdujimos cómo los depuradores pueden ganar control y acceder a información de bajo nivel en el proceso objetivo mediante la llamada al sistema ptrace(). En esta ocasión vamos a tratar una de las funciones más útiles que proporcionan los depuradores, la de establecer breakpoints. En general, un breakpoint es una ubicación designada por el usuario en el programa donde el usuario desea recuperar el control y examinar el estado del programa si la ejecución llega alguna vez a esa ubicación. Los breakpoints pueden ser tanto hardware como software. GDB puede establecer breakpoints hardware de tres maneras distintas:
- 1. A través de registros dedicados en los que se almacena la dirección del punto de interrupción y después se comprueba si el contador de programa coincide con el valor de alguno de los registros.
- 2. Cuando se está utilizando un emulador que incluye circuitos que monitorizan las líneas de direcciones de salida del procesador y detienen la ejecución si coinciden con la dirección de un punto de interrupción.
- 3. Cuando el objetivo tiene la habilidad propia de establecer breakpoints, como por ejemplo, un monitor ROM que es capaz de establecer sus propios breakpoints software, que aunque no sean breakpoints hardware literales, para GDB si lo son.
Como los breakpoints hardware no están siempre disponibles, se necesita un método para establecer breakpoints software, a grandes rasgos:
- 1. GDB guarda internamente la instrucción original en la dirección del punto de interrupción y la reemplaza por una interrupción (por ejemplo, INT3 en x86) o una instrucción inválida (por ejemplo, una división ilegal) que cause una excepción.
- 2. GDB recibe la señal de que ha ocurrido una excepción (SIGCHLD) y comprueba si la dirección del contador de programa está en la lista de breakpoints, si es así, se trata de un punto de interrupción, si no, es un fallo producido por el programa.
- 3. El depurador se encuentra detenido en el punto de interrupción y el usuario realiza las operaciones que considere necesarias.
- 4. Para reanudar la ejecución, GDB recupera la instrucción original, ejecuta la instrucción en modo single-step, vuelve a introducir la interrupción y, por último, continúa con la ejecución normal.
GDB proporciona otra funcionalidad además de los breakpoints. Echar un ojo a la documentación.