¿Puedo establecer un punto de interrupción en 'acceso a memoria' en GDB?

244

Estoy ejecutando una aplicación a través de gdb y quiero establecer un punto de interrupción para cada vez que se acceda / cambie una variable específica. ¿Hay un buen método para hacer esto? También estaría interesado en otras formas de monitorear una variable en C / C ++ para ver si / cuando cambia.

TJ Seabrooks
fuente

Respuestas:

286

el reloj solo interrumpe en la escritura, el reloj le permite interrumpir en la lectura y el reloj le permite interrumpir en la lectura / escritura.

Puede establecer puntos de observación de lectura en ubicaciones de memoria:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

pero una limitación se aplica a los comandos rwatch y awatch; no puedes usar variables gdb en expresiones:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

Entonces debes expandirlos tú mismo:

gdb$ print $ebx 
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

Editar: Ah, y por cierto. Necesita soporte de hardware o software . El software es obviamente mucho más lento. Para saber si su sistema operativo admite puntos de observación de hardware, puede ver la configuración del entorno can-use-hw-watchpoints .

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.
askol
fuente
77
Si desea ver un miembro del método de C ++, me encontré con esta variante inmensamente útil: watch -location mTextFormatted.
Ivan Vučica
¿Qué pasa si no tengo la dirección de una variable? ¿Puedo usar su nombre?
Raffi Khatchadourian
55
Puede hacer que GDB imprima la dirección de la variable con la dirección del operador. print &variable
Loduwijk
1
Esta respuesta no dice nada sobre el tamaño de la ubicación de la memoria que se observa mediante watchcomandos. Mientras tanto, esta es la primera pregunta que me viene a la mente después de leer lo anterior. ¿Cuántos bytes rwatch *0xfeedfacemirarán realmente?
ANT
8
@AnT, estaba asumiendo que vería un solo byte, lo que parece ser el caso, pero puede convertirlo a un tipo específico, por ejemplo, rwatch *(int *)0xfeedfacey verá sizeof(int)bytes: sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints. html
askol
28

Lo que estás buscando se llama punto de observación .

Uso

(gdb) watch foo: ver el valor de la variable foo

(gdb) watch *(int*)0x12345678: mire el valor señalado por una dirección , emitido al tipo que desee

(gdb) watch a*b + c/d: mira una expresión compleja arbitraria , válida en el idioma nativo del programa

Los puntos de observación son de tres tipos:

  • watch : gdb se romperá cuando ocurra una escritura
  • rwatch : BGF se romperá wnen una lectura ocurre
  • awatch : gdb se romperá en ambos casos

Puede elegir el más apropiado para sus necesidades.

Para más información, mira esto .

Paolo M
fuente
55
Escribí otra respuesta porque las existentes no me parecían muy sencillas ...
Paolo M
25

Suponiendo que la primera respuesta se refiere a la sintaxis tipo C (char *)(0x135700 +0xec1a04f), la respuesta rwatch *0x135700+0xec1a04fes incorrecta. La sintaxis correcta es rwatch *(0x135700+0xec1a04f).

La falta de ()s allí me causó mucho dolor al tratar de usar los puntos de observación.

Smirnov
fuente
9

Acabo de intentar lo siguiente:

 $ cat gdbtest.c
 int abc = 43;

 int main()
 {
   abc = 10;
 }
 $ gcc -g -o gdbtest gdbtest.c
 $ gdb gdbtest
 ...
 (gdb) watch abc
 Hardware watchpoint 1: abc
 (gdb) r
 Starting program: /home/mweerden/gdbtest 
 ...

 Old value = 43
 New value = 10
 main () at gdbtest.c:6
 6       }
 (gdb) quit

Por lo tanto, parece posible, pero parece que necesita algún soporte de hardware.

mweerden
fuente
Si su plataforma no admite puntos de observación de hardware, el gdb debería recurrir a un punto de observación de software.
Tod
2

Use watch para ver cuándo se escribe una variable, rwatch cuando se lee y awatch cuando se lee / escribe de / a, como se indicó anteriormente. Sin embargo, tenga en cuenta que para usar este comando, debe romper el programa y la variable debe estar dentro del alcance cuando haya roto el programa:

Usa el comando de vigilancia. El argumento del comando watch es una expresión que se evalúa. Esto implica que la variable en la que desea establecer un punto de observación debe estar en el alcance actual. Por lo tanto, para establecer un punto de observación en una variable no global, debe haber establecido un punto de interrupción que detendrá su programa cuando la variable esté dentro del alcance. Establece el punto de observación después de que el programa se interrumpe.

higgs241
fuente