valor resueltos proyectos practico gestion gerencia ganado ejercicios caso c debugging automation gdb

resueltos - ¿Cómo imprimir cada línea ejecutada en GDB automáticamente hasta que se alcanza un punto de corte determinado?



valor ganado excel (4)

¿Qué tal si se hace así en gdb, usando un archivo de comando? Cambie el argumento del archivo y cuente el bucle según sea necesario.

gdb -x run.gdb

run.gdb:

set pagination off set logging file gdb.log set logging on set $i = 0 file main break main break WriteData # sadly, commands not getting executed on reaching breakpoint 2 commands 2 set $i=1000 print "commands 2 : %d",$i end run while ( $i < 1000 ) step # next # continue set $i = $i + 1 end

Me gustaría poder establecer un punto de interrupción en GDB y llevarlo hasta ese punto, y en el proceso, imprimir las líneas que ha "pisado".

Aquí hay un ejemplo, basado en este archivo simple con un main y una función, y dos puntos de interrupción para cada uno:

$ cat > test.c <<EOF #include "stdio.h" int count=0; void doFunction(void) { // two steps forward count += 2; // one step back count--; } int main(void) { // some pointless init commands; count = 1; count += 2; count = 0; //main loop while(1) { doFunction(); printf("%d/n", count); } } EOF $ gcc -g -Wall test.c -o test.exe $ chmod +x test.exe $ gdb -se test.exe ... Reading symbols from /path/to/test.exe...done. (gdb) b main Breakpoint 1 at 0x80483ec: file test.c, line 14. (gdb) b doFunction Breakpoint 2 at 0x80483c7: file test.c, line 7.

Para iniciar la sesión, necesito ejecutar ( r ) el programa, que luego se detendrá en el primer punto de interrupción ( main ):

(gdb) r Starting program: /path/to/test.exe Breakpoint 1, main () at test.c:14 14 count = 1; (gdb)

En este punto, puedo, por ejemplo, presionar continuar ( c ); y el proceso se ejecutará, sin generar ningún resultado, y se interrumpirá en la línea solicitada:

(gdb) c Continuing. Breakpoint 2, doFunction () at test.c:7 7 count += 2; (gdb)

Por otro lado, en lugar de continuar, puedo ir línea por línea, ya sea usando paso ( s ) o siguiente ( n ); por ejemplo:

14 count = 1; (gdb) n 15 count += 2; (gdb) s 16 count = 0; (gdb) s 19 doFunction(); (gdb) s Breakpoint 2, doFunction () at test.c:7 7 count += 2; (gdb) s 9 count--; (gdb) s 10 } (gdb) s main () at test.c:20 20 printf("%d/n", count); (gdb) s ... (gdb) s _IO_vfprintf_internal (s=Cannot access memory at address 0xe5853361 ) at vfprintf.c:210 210 vfprintf.c: No such file or directory. in vfprintf.c (gdb) s 245 in vfprintf.c (gdb) s 210 in vfprintf.c (gdb) n 245 in vfprintf.c ... (gdb) n 2006 in vfprintf.c (gdb) n __printf (format=0x80484f0 "%d/n") at printf.c:39 39 printf.c: No such file or directory. in printf.c (gdb) n main () at test.c:21 21 } (gdb) n 19 doFunction(); (gdb) n Breakpoint 2, doFunction () at test.c:7 7 count += 2; (gdb)

De todos modos, soy consciente de que puedo mantener presionado Enter , y el último comando ingresado (paso o siguiente) se repetirá ( dejó sesión un poco más larga en el segundo caso, para mostrar que ''next'' sigue en el mismo nivel, pasos ''step'' dentro de las funciones que se llaman ). Sin embargo, como se puede ver, dependiendo de si el paso o las próximas ejecuciones, puede tomar un tiempo hasta que se llegue a un resultado, así que no quiero sentarme durante 10 minutos con la mano pegada en el botón Enter :)

Entonces, mi pregunta es: ¿de alguna manera puedo ordenar a gdb que corra al "punto de corte 2" sin más intervención del usuario, mientras imprimo las líneas por las que pasa, como si se hubiera presionado el paso (o el siguiente)?


Basado en el enlace en la respuesta de @ sdaau ( http://www.mail-archive.com/[email protected]/msg00031.html ), creé mi propio script para simplemente seguir enviando ''s'' y leyendo el resultado de gdb de forma continua, mientras imprime salida en archivo de texto y terminal, por supuesto, mi script puede modificarse para adaptarse a las necesidades de los demás, sin embargo, espero que la modificación que hice se ajuste a la mayoría de las necesidades de la gente.

http://www.codeground.net/coding/gdb-step-into-all-lines-to-get-full-application-flow/

wget http://www.codeground.net/downloads/gdbwalkthrough.c gcc gdbwalkthrough.c -o gdbwalkthrough ./gdbwalkthrough <application full path> [application arguments]


Bueno, esto no fue fácil, pero creo que de alguna manera lo entendí :) Pasé por un montón de intentos fallidos (publicados here ); el código relevante está abajo.

Básicamente, el problema en un "siguiente / paso hasta el punto de interrupción" es cómo determinar si está "en" un punto de interrupción o no, si el depurador se detiene (en un paso). Tenga en cuenta también que uso GDB 7.2-1ubuntu11 (actual para Ubuntu 11.04). Entonces, fue así:

  • Primero encontré acerca de las variables de conveniencia , y pensé que, dado que hay contadores de programas y tal disponibilidad, debe haber alguna variable de conveniencia GDB que proporcione el estado de "punto de interrupción" y se puede usar directamente en un script de GDB. Sin embargo, después de mirar el índice de referencia de GDB por un tiempo, simplemente no puedo encontrar ninguna de esas variables (mis intentos están en nub.gdb )
  • A falta de dicha variable interna de "estado de punto de interrupción", lo único que queda por hacer es capturar la salida de línea de comando (''stdout'') de GDB (en respuesta a los comandos) como una cadena, y analizarla (buscar) Punto de interrupción ")
  • Luego, descubrí Python API a GDB, y el gdb.execute("CMDSTR", toString=True) - que aparentemente es exactamente lo que se necesita para capturar la salida: " Por defecto, cualquier salida producida por comando se envía a la salida estándar de gdb. Si el parámetro to_string es True, la salida será recopilada por gdb.execute y devuelta como una cadena [ 1 ] "!

Y finalmente, el enfoque que funcionó fue: redirigir temporalmente la salida de GDB desde un gdb.execute a un archivo de registro en RAM (Linux: /dev/shm ); y luego leerlo de nuevo, analizarlo e imprimirlo desde python: python también maneja un ciclo while simple que da pasos hasta llegar a un punto de interrupción.

La ironía es que la mayoría de estos errores, que causaron esta solución mediante la redirección del archivo de registro, en realidad se corrigieron recientemente en SVN; lo que significa que se propagarán a las distribuciones en el futuro cercano, y uno podrá usar gdb.execute("CMDSTR", toString=True) directamente: / Sin embargo, como no puedo arriesgarme a generar GDB desde la fuente en este momento (y posiblemente en posibles nuevas incompatibilidades), esto es lo suficientemente bueno para mí también :)

Aquí están los archivos relevantes (parcialmente también en pygdb-fork.gdb , pygdb-fork.py ):

pygdb-logg.gdb es:

# gdb script: pygdb-logg.gdb # easier interface for pygdb-logg.py stuff # from within gdb: (gdb) source -v pygdb-logg.gdb # from cdmline: gdb -x pygdb-logg.gdb -se test.exe # first, "include" the python file: source -v pygdb-logg.py # define shorthand for nextUntilBreakpoint(): define nub python nextUntilBreakpoint() end # set up breakpoints for test.exe: b main b doFunction # go to main breakpoint run

pygdb-logg.py es:

# gdb will ''recognize'' this as python # upon ''source pygdb-logg.py'' # however, from gdb functions still have # to be called like: # (gdb) python print logExecCapture("bt") import sys import gdb import os def logExecCapture(instr): # /dev/shm - save file in RAM ltxname="/dev/shm/c.log" gdb.execute("set logging file "+ltxname) # lpfname gdb.execute("set logging redirect on") gdb.execute("set logging overwrite on") gdb.execute("set logging on") gdb.execute(instr) gdb.execute("set logging off") replyContents = open(ltxname, ''r'').read() # read entire file return replyContents # next until breakpoint def nextUntilBreakpoint(): isInBreakpoint = -1; # as long as we don''t find "Breakpoint" in report: while isInBreakpoint == -1: REP=logExecCapture("n") isInBreakpoint = REP.find("Breakpoint") print "LOOP:: ", isInBreakpoint, "/n", REP

Básicamente, pygdb-logg.gdb carga el script pygdb-logg.py python, configura el alias nub para nextUntilBreakpoint e inicializa la sesión; todo lo demás lo maneja el script python. Y aquí hay una sesión de muestra: con respecto a la fuente de prueba en OP:

$ gdb -x pygdb-logg.gdb -se test.exe ... Reading symbols from /path/to/test.exe...done. Breakpoint 1 at 0x80483ec: file test.c, line 14. Breakpoint 2 at 0x80483c7: file test.c, line 7. Breakpoint 1, main () at test.c:14 14 count = 1; (gdb) nub LOOP:: -1 15 count += 2; LOOP:: -1 16 count = 0; LOOP:: -1 19 doFunction(); LOOP:: 1 Breakpoint 2, doFunction () at test.c:7 7 count += 2; (gdb) nub LOOP:: -1 9 count--; LOOP:: -1 10 } LOOP:: -1 main () at test.c:20 20 printf("%d/n", count); 1 LOOP:: -1 21 } LOOP:: -1 19 doFunction(); LOOP:: 1 Breakpoint 2, doFunction () at test.c:7 7 count += 2; (gdb)

... justo como yo lo quería: P Simplemente no sé qué tan confiable es ( y si será posible usarlo en avr-gdb , que es para lo que necesito esto :) EDIT: versión de avr-gdb en Ubuntu 11.04 es actualmente 6.4, que no reconoce el comando python :( )

Bueno, espero que esto ayude a alguien,
¡Aclamaciones!

Aquí algunas referencias:


Como una nueva respuesta, ya que lo anterior ya está acallado :) Básicamente, si el punto es observar la ejecución de las líneas de código de origen (y / o ensamblado) como el programa en ejecución, como la motivación a menudo es para mí al buscar en " automático impresión "- entonces, básicamente, una forma muy rápida es usar el modo GDB TUI; Yo cito:

c - comportamiento del gdb: valor optimizado - Desbordamiento de pila # 1354762

Use el modo GDB TUI. Mi copia de GDB lo habilita cuando escribo el signo menos y Enter. Luego escriba Cx 2 (que es mantener presionado Control y presione X, suelte ambos y luego presione 2). Eso lo pondrá en la pantalla de fuente y desensamblaje divididos. Luego use stepi y nexti para mover una instrucción de máquina a la vez. Use Cx o para alternar entre las ventanas de TUI.

El truco aquí es que, incluso si presionas continue - esta fuente de tiempo se mostrará e indicará en la TUI; y seguido mientras el programa se ejecuta:

... y esto para mí evita muchas situaciones en las que tendría que guiar los puntos de interrupción en el "contexto de auto-escalonamiento" (aunque todavía existen tales situaciones) .. Documentos sobre TUI: TUI - Depuración con GDB

¡Aclamaciones!