subaru - gdb tutorial
gdb se detiene con demasiados puntos de observación cuando solo hay uno (3)
¿Conoces otras razones por las cuales no se pudo insertar un punto de observación aparte de demasiados puntos de interrupción / puntos de observación de hardware?
Tengo la siguiente sesión de depuración:
GNU gdb (GDB) 7.1
...
(gdb) watch itrap_t_beg[1][222]
Hardware watchpoint 1: itrap_t_beg[1][222]
(gdb) cont
Continuing.
...
Hardware watchpoint 1: itrap_t_beg[1][222]
...
(gdb) cont
Continuing.
Warning:
Could not insert hardware watchpoint 1.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
(gdb) info break
Num Type Disp Enb Address What
1 hw watchpoint keep y itrap_t_beg[1][222]
breakpoint already hit 1 time
Como puede ver, solo hay un punto de observación pero no puede insertar el punto de interrupción.
¿Sabes cómo puedo solucionar esto?
Por lo que sé, las CPU x86 de commodity tienen cuatro registros de depuración disponibles para soportar interrupciones / relojes de hardware. Esto limita el tamaño del objeto que puedes ver. La alineación de objetos también se reproduce aquí.
Intente limitar el alcance del reloj a un objeto más pequeño, como el par del primer y último miembro de la estructura.
Puede forzar puntos de interrupción del software (que no tienen límite de tamaño) ejecutando
establecer can-use-hw-watchpoints 0
Respuesta al disparo: use el watch -location itrap_t_beg[1][222]
, o el formato abreviado watch -l
.
Respuesta larga: Citando el manual de GDB :
Ver expresiones complejas que hacen referencia a muchas variables también puede agotar los recursos disponibles para los puntos de observación asistidos por hardware. Eso es porque gdb necesita ver cada variable en la expresión con recursos asignados por separado.
gdb mira literalmente la expresión misma, no la dirección a la que apunta. En este caso, significa que el punto de interrupción se itrap_t_beg
si itrap_t_beg
se cambia de manera tal que itrap_t_beg[1][222]
haga; no solo hay un punto de itrap_t_beg[1][222]
para itrap_t_beg[1][222]
, sino también uno para itrap_t_beg
. Esto puede ser más de lo que está disponible.
En tu caso, itrap_t_beg
es 7 itrap_t_beg
, 28 bytes. Un punto de observación x86_64 tiene hasta ocho bytes, por lo que GDB necesita cuatro puntos de observación para toda la estructura, más un quinto para itrap_t_beg
. La familia x86 solo admite cuatro puntos de observación simultáneos.
Un ejemplo más completo sobre cómo funcionan los puntos de observación:
//set a watchpoint on ''*p'' before running
#include <stdio.h>
int a = 0;
int b = 0;
int c = 0;
int* p = &a;
int main()
{
puts("Hi"); // Dummy lines to make the results clearer, watchpoints stop at the line after the change
*p = 1; // Breaks: *p was changed from 0 to 1
puts("Hi");
a = 2; // Breaks: a is *p, which changed from 1 to 2
puts("Hi");
p = &b; // Breaks: p is now b, changing *p from 2 to 0
puts("Hi");
p = &c; // Doesn''t break: while p changed, *p is still 0
puts("Hi");
p = NULL; // Breaks: *p is now unreadable
puts("Hi");
return 0;
}
En teoría, esta es una característica útil; Puedes ver una expresión compleja, rompiendo tan pronto como sea falsa, algo así como una afirmación constantemente probada. Por ejemplo, puede watch a==b
en el programa anterior.
En la práctica, es inesperado, a menudo desencadena este problema y generalmente no es lo que desea.
Para ver solo la dirección de destino, use watch -location itrap_t_beg[1][222]
. (Esto está disponible a partir de GDB 7.3, lanzado en julio de 2011. Si todavía está en 7.1, use print &itrap_t_beg[1][222]
y watch *(itrap_t)0x12345678
, o la dirección que imprima).