2010-03-15 11 views
12

En una aplicación de gran C, que han establecido un punto de observación de hardware en una dirección de memoria de la siguiente manera:Punto de observación del hardware GDB muy lento - ¿por qué?

(gdb) watch *0x12F5D58 
Hardware watchpoint 3: *0x12F5D58 

Como se puede ver, se trata de un punto de observación de hardware, no de software, lo que explicaría la lentitud.

Ahora el tiempo de ejecución de la aplicación en el depurador ha cambiado de menos de diez segundos a una hora y el recuento. El punto de observación se ha disparado tres veces hasta ahora, la primera vez después de 15 minutos cuando la página de memoria que contiene la dirección se hizo legible por sbrk. Seguramente durante esos 15 minutos, el punto de observación debería haber sido eficiente ya que la página de memoria era inaccesible. Y eso todavía no explica, por qué es tan lento después.

La plataforma es x86_64 y las versiones de GDB son Ubuntu 9.10 paquete:

$ gdb --version 
GNU gdb (GDB) 7.0-ubuntu 
[...] 

y de la GDB 7.1 construido a partir de fuentes:

$ gdb-7.1 --version 
GNU gdb (GDB) 7.1 

Gracias de antemano por alguna idea de lo que podría ser el causa o cómo solucionarlo/solucionarlo.

EDIT: eliminado fundido

EDIT: GDB 7.1

+0

¿Siempre es lento cuando se ejecuta bajo el depurador o solo cuando tiene un conjunto de puntos de observación? – Gabe

+1

Solo con punto de observación. –

Respuesta

5

En realidad, tuve problemas con los puntos de observación de hardware en GDB 7.x.x., lo cual no es aceptable ya que los puntos de observación son una necesidad en mi trabajo.

Por consejo de un compañero de trabajo, descargué la fuente para 6.7.1 y la construí localmente. Los puntos de observación funcionan mucho mejor ahora.

Puede valer la pena intentarlo.

+0

Interesante. Voy a probar esto. –

+1

GDB 6.7.1 falta una característica donde se pueden usar los puntos de vigilancia en la dirección de la memoria que es inaccesible en el momento de configuración del punto de vigilancia. Es posible habilitarlo en el momento correcto, pero esto será más complicado, lo intentaré más adelante. También intenté liberar GDB 7.1, el mismo problema que con 7.0. –

+0

con puntos de corte condicionales y comandos de punto de interrupción, es posible que pueda solucionarlo sin demasiados problemas. – alesplin

4

Es más probable debido a que estas lanzando cada vez. Prueba esto:

(gdb) watch *0x12F5D58 

Otra opción es que usted tiene demasiados puntos de observación conjunto de hardware, por lo que GDB se ve obligado a utilizar puntos de observación de software. Intente verificar cuántos puntos de control tiene:

(gdb) info break 

y vea si puede deshabilitar algunos puntos de observación.

+0

¿Puede gdb realmente desreferenciar un literal entero, sin necesidad de saber a qué tipo corresponde la desreferencia? Esa no es una expresión C válida, al menos ... – unwind

+0

Sí, puede. Lo hago todo el tiempo. –

+1

Para mi sorpresa (pensé que GDB solo acepta expresiones C) "watch * 0x12F5DF8" funciona, pero es tan lento como la versión anterior. –

1

En x86 tiene la siguiente limitación: todos sus puntos de observación pueden cubrir no más de cuatro direcciones de memoria, cada dirección de memoria puede ver una palabra de memoria - esto es porque los puntos de observación del hardware (los rápidos) usan los procesadores para depurar registros , usted tiene cuatro de ellos, por lo tanto, cuatro lugares para observar.

+1

Él ya dijo que solo tenía un único punto de observación, vea el cuarto comentario a la respuesta de Nathan. –

5

Descubrí que ver un búfer de caracteres grandes era muy lento, mientras que ver un carácter en ese búfer era muy rápido.

p. Ej.

static char buf[1024]; 
static char* buf_address = &buf; 

watch buf_address - muy lento.

watch *buf_address - muy rápido.