2010-12-07 10 views
23

Tengo un proceso que es llamado por otro proceso que es llamado por otro proceso y así sucesivamente hasta el final. Es un proceso secundario en una larga cadena de herramientas.¿Hay alguna manera de decirle a gdb que espere a que comience un proceso y se conecte a él?

Este proceso se cuelga.

Me gustaría ver este proceso en gdb para entender por qué está fallando. Sin embargo, la única forma en que se me ocurre es:

  1. iniciar el proceso principal original en la línea de comandos.
  2. encuesta ps -C <name process I want to catch> y obtenga el PID.
  3. ejecute gdb, adjunto al PID de ese proceso.

Esto es engorroso pero generalmente hace el trabajo. El problema es que la falla actual se ejecuta muy rápido, y para cuando capture el PID y ejecute gdb, ya pasó el punto de falla.

me gustaría lanzar el BGF y en lugar de:

(gdb) attach <pid> 

me gustaría hacer:

(gdb) attach <process name when it launches> 

¿Hay alguna manera de hacer esto?


estoy usando GDB 7.1 en Linux

Respuesta

5

Puede adjuntar a un proceso padre y puesta a modo de seguimiento tenedor niño. Esto hará que gdb depure el proceso hijo en lugar de padre después de bifurcar. También captura tenedor será útil. Esto hará que gdb se detenga después de cada tenedor. Ver docs.

+0

Pero esto puede ser bastante tedioso si el árbol de proceso es profundo (como es en mi caso) –

+0

@NathanFellman - Una solución para la tediosidad podría ser escribir algún código de extensión de Python para gdb que automatice este proceso. Podría despertarse después de cada horquilla atrapada, determinar si esa horquilla es relevante, luego continuar si no es así. – Omnifarious

1

No es exactamente lo que esperaba, pero podría ayudarle en la depuración.

valgrind --trace-children=yes your_program 

comprobará y errores de memoria de impresión en todos los niños del proceso, con el seguimiento de la pila y algunos detalles acerca del error (por ejemplo. En el caso de doble liberación, se obtendría el seguimiento de pila de la primera conexión)

Además, puede hacer que el proceso de bloqueo genere un volcado del núcleo y depurar esta autopsia. Ver this answer for details.

8

En Mac OS X, puede utilizar:

(gdb) attach --waitfor <process-name> 

pero esto también es a veces incapaz de capturar los procesos que salen muy rápidamente. No estoy seguro de si esto es compatible con otras plataformas.

GDB Release Notes for Mac OS X v10.5 WWDC Seed

+0

Eso es lo que estoy buscando. Desafortunadamente, parece no ser compatible en mi versión (7.2) –

+0

, así como en la versión 7.3.1 –

+2

Usar gdb-apple: sudo port install gdb-apple –

1

que he tenido que hacer frente a un problema similar con algo que estoy tratando de depuración, y se me ocurrió una solución utilizando ldpreload, pero después de ver a Joeys responden Creo que voy a tratar de que en primer lugar.En caso de que sea útil para cualquier otra persona, esta es la idea:

Crear una biblioteca LD_PRELOAD para enganchar las llamadas exec * (hay muchas guías sobre cómo hacer esto, pero si hago esto, actualizaré mi respuesta con el código), verifique la ruta utilizada al pasar por la llamada exec *, si es nuestro objetivo, luego envíe un mensaje con el PID a stderr y entre en un bucle infinito (con suspensión para evitar el uso masivo de la CPU). Luego puede adjuntar con gdb y modificar el registro utilizado en el ciclo para continuar la ejecución.

Esto puede implicar un ASM en línea para asegurarse de que el compilador no optimice el ciclo infinito de tal manera que dificulte la ruptura. Una forma más elocuente de hacerlo sería encontrar una forma de detectar que gdb se ha conectado y luego disparar un punto de interrupción ("asm (" int3 ");" debería hacer el truco en este último ").

15

Aquí está mi script llamado gdbwait:

#!/bin/sh 
progstr=$1 
progpid=`pgrep -o $progstr` 
while [ "$progpid" = "" ]; do 
    progpid=`pgrep -o $progstr` 
done 
gdb -ex continue -p $progpid 

Uso:

gdbwait my_program 

Claro que se puede escribir más agradable, pero la sintaxis de secuencia de comandos shell Bourne es doloroso para mí por lo que si funciona, entonces lo dejo solo. :) Si el nuevo proceso se inicia y muere demasiado rápido, agregue 1 segundo de retraso en su propio programa para la depuración ...

+0

gracias. es muy útil. –

Cuestiones relacionadas