2009-08-25 12 views
6

Tengo una aplicación. Tengo el código fuente (en C). Puedo compilarlo de todos modos, quiero. Agregue cualquier herramienta que quiera. Etc. Sin embargo, no quiero rociar el código fuente con un montón de printf. Quiero poder crear un registro de algún tipo que muestre cuándo se escribe un valor particular (por ejemplo, algún miembro de una estructura global) (su valor cambia). Me gustaría poder mostrar el archivo de origen y el número de línea, y el valor antiguo y nuevo.ayuda con gdb traces (o similar)

También me gustaría poder especificar el valor por nombre, no por dirección. Pero la dirección está bien. Puntos de bonificación si puedo especificar un valor que sea local para una función.

Todavía me estoy rascando la cabeza tratando de descubrir los comandos de rastreo de gdb. Cualquier ayuda es muy apreciada. Gracias.

Respuesta

1

Gracias a ambos @derobert y @peter! Finalmente volví a esto, y esto:

break main 
commands 
     watch somevar 
     commands 
       cont 
     end 
     cont 
end 
run 

hace el truco. Esto funciona cuando "somevar" es global o local a "principal". Si "somevar" es local para la función antera, simplemente reemplace "main" con el nombre de la función anterior.

poner estos comandos en un archivo (por ejemplo, "gdbscript") y ejecutar el BGF como:

gdb -x gdbscript a.out 
6

En primer lugar, deberá asegurarse de compilar su programa con símbolos de depuración, y probablemente sin optimización para que gdb sea más útil. Para gcc, eso sería -g -O0.

En segundo lugar, la característica que está buscando no es el rastreo, sus puntos de observación.

(gdb) help watch 
Set a watchpoint for an expression. 
A watchpoint stops execution of your program whenever the value of 
an expression changes. 

Así, dado un código de ejemplo:

int main() { 
    int a; 
    a = 1; 
    a = 2; 
    return 0; 
} 

a continuación, puede ejecutar gdb en él, y:

(gdb) b main 
Breakpoint 1 at 0x80483a5: file test.c, line 4. 
(gdb) run 
Starting program: /tmp/test 

Breakpoint 1, main() at test.c:4 
4    a = 1; 
(gdb) watch a 
Hardware watchpoint 2: a 
(gdb) c 
Continuing. 
Hardware watchpoint 2: a 

Old value = -1207552288 
New value = 2 
main() at test.c:8 
8    return 0; 

que está funcionando un poco divertido debido a un ser en la pila, no memoria Y si la optimización estuviera activada, funcionaría aún menos: a se optimizaría.

+1

Trate declarar 'a' 'como int' volátil, que puede hacer que el ejemplo funcione mejor. – caf

+0

Gracias derobert. Por lo que entiendo acerca de los relojes es que hacen que la ejecución del programa cese hasta que el usuario "continúe". Estoy seguro de que podría escribir un script esperado para hacer esto, pero ¿hay alguna forma de hacerlo automáticamente desde dentro de gdb? – tvaughan

+0

@tvaughan: No conozco una forma automática de hacerlo dentro de gdb. – derobert

3

Como se indicó anteriormente, debe establecer un punto de observación en su variable.

El que utilice el comando "comandos"

(gdb) help commands 
Set commands to be executed when a breakpoint is hit. 
Give breakpoint number as argument after "commands". 
With no argument, the targeted breakpoint is the last one set. 
The commands themselves follow starting on the next line. 
Type a line containing "end" to indicate the end of them. 
Give "silent" as the first line to make the breakpoint silent; 
then no output is printed when it is hit, except what the commands print. 

lo tanto, encontrar el número de punto de observación desde el comando reloj, y hacer esto (suponiendo que su reloj es el segundo descanso)

(gdp) commands 2 
> print a 
> cont 
> end 

Asumiendo a es la variable que quieres. Puede omitir la línea de impresión si está contento con la salida que gdb le brinda de todos modos.

También puede usar los comandos en su punto de interrupción original para establecer el punto de observación y continuar.