2009-04-29 6 views
32

¿Alguien me puede decir cómo hacer la depuración en tiempo de ejecución en las bibliotecas compartidas?¿Cómo depurar las bibliotecas compartidas en tiempo de ejecución?

Necesito una función de depuración en tiempo de ejecución en mi biblioteca compartida, pero es llamada por otro programa. ¿Cómo puedo hacer algo como dbx con bibliotecas compartidas?

Estoy usando dbx en AIX. es gdb mejor que dbx por lo que estoy tratando de hacer ?.

Respuesta

28

Solo necesita llamar a gdb con el ejecutable (no importa si es suyo o de un tercero). Aquí hay un ejemplo donde depuro el comando ls y establezco un punto de interrupción en la biblioteca (compartida) c. En este ejemplo se utiliza GDB 6.8 que soporta diferido puntos de ruptura (pendiente), que lo hace fácil:

gdb /bin/ls 
GNU gdb 6.8-debian 
Copyright (C) 2008 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu"... 
(no debugging symbols found) 
(gdb) b write 
Function "write" not defined. 
Make breakpoint pending on future shared library load? (y or [n]) y 
Breakpoint 1 (write) pending. 
(gdb) r 
Starting program: /bin/ls 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
[Thread debugging using libthread_db enabled] 
(no debugging symbols found) 
(no debugging symbols found) 
[New Thread 0x7f98d2d23780 (LWP 7029)] 
[Switching to Thread 0x7f98d2d23780 (LWP 7029)] 

Breakpoint 1, 0x00007f98d2264bb0 in write() from /lib/libc.so.6 
(gdb) 

Como se puede ver GDB gestiona automáticamente todos los hilos utilizados por el ejecutable. No tiene que hacer nada especial para hilos allí. El punto de interrupción funcionará en cualquier hilo.

Alternativamente, si desea adjuntar el depurador a una aplicación ya se está ejecutando (yo uso tail -f/tmp/TTT aquí como un ejemplo):

ps ux | grep tail 
lothar 8496 0.0 0.0 9352 804 pts/3 S+ 12:38 0:00 tail -f /tmp/ttt 
lothar 8510 0.0 0.0 5164 840 pts/4 S+ 12:39 0:00 grep tail 

gdb 
GNU gdb 6.8-debian 
Copyright (C) 2008 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu"... 
(no debugging symbols found) 
(gdb) attach 8496 
Attaching to program: /usr/bin/tail, process 8496 
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done. 
Loaded symbols for /lib/librt.so.1 
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done. 
Loaded symbols for /lib/libc.so.6 
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done. 
[Thread debugging using libthread_db enabled] 
[New Thread 0x7f24853f56e0 (LWP 8496)] 
Loaded symbols for /lib/libpthread.so.0 
Reading symbols from /lib/ld-linux-x86-64.so.2... 
(no debugging symbols found)...done. 
Loaded symbols for /lib64/ld-linux-x86-64.so.2 
(no debugging symbols found) 
0x00007f2484d2bb50 in nanosleep() from /lib/libc.so.6 
(gdb) b write 
Breakpoint 1 at 0x7f2484d57bb0 
(gdb) c 
Continuing. 
[Switching to Thread 0x7f24853f56e0 (LWP 8496)] 

Breakpoint 1, 0x00007f2484d57bb0 in write() from /lib/libc.so.6 
(gdb) 
+0

I utilizó dbx en AIX. si dices que gdb puede hacerlo con aplicaciones de subprocesos ... entonces dbx apesta a lo grande ... y he sido un completo tonto por usarlo todo este tiempo. –

+0

Sad gdb no funciona correctamente en AIX ... AIX sucks .. –

+0

No sé dbx, pero debería tener características similares – lothar

9

Normalmente, el procedimiento para depurar una biblioteca compartida es muy similar a la depuración de un ejecutable; la diferencia principal es que es posible que no pueda establecer un punto de interrupción hasta que la biblioteca compartida se cargue en la memoria. Usted conecta el depurador al ejecutable principal.

Si está depurando una aplicación que no es de su propiedad, pero está utilizando su módulo en una arquitectura de complemento, aún utiliza el mismo método. Asegúrese (como siempre) de que tiene información de depuración disponible para su biblioteca compartida. En Windows, generaría un archivo .pdb. Con gcc, creo que especifica un indicador de compilador especial (-g?) Para asegurarse de que se proporciona la información de depuración. Adjunta el depurador a la aplicación de terceros.

+0

¿Qué sucede si el ejecutable principal no es mío y es de terceros ... pero estoy escribiendo un módulo que será utilizado por el tercero ... ¿Cómo se depura entonces? –

+0

Aún inicia el ejecutable (o lo asocia a un proceso) con gdb. Después de cargar la biblioteca, gdb puede establecer puntos de interrupción allí sin problema. – lothar

+0

Pero cuando establece un punto de interrupción en su código de lib compartido y si el ejecutable principal lo llama, ¿no se bloqueará el ejecutable principal? –

1

Recuerdo probar bibliotecas compartidas mediante la creación de una aplicación simulada que lo usaba. Si está dispuesto a hacer mucho trabajo, podría crear una segunda biblioteca compartida de simulación que solo recopile información sobre cómo la aplicación de terceros está utilizando la biblioteca y luego haga que su aplicación simulada vuelva a reproducir esa información.

Por supuesto, nunca dude del poder de las llamadas printf y fprintf bien colocadas.

0

Puede intentar compilar y vincular la biblioteca estáticamente para depurarla.
Si su error solo aparece cuando se compila como compartido, entonces eso podría darle algunas pistas.

1

Ha sido un largo tiempo desde que Tuve que usar dbx en AIX, y me enfrenté a este problema también. Instalar gdb no era una opción para mí.

dbx /path/to/your/program 
(dbx) run [args to your program] 
(dbx) set $ignoreonbptrap   # I kept hitting a trace/bpt trap 
(dbx) set $deferevents    # allows setting bp in not loaded shared library 
(dbx) set $repeat     # useful, repeat commands with <enter> tjust like gdb 
(dbx) stop in MySharedLibraryFunc # defers breakpoint 
(dbx) cont 
3

Otro ejemplo aún más a la respuesta de Lothar:

estoy corriendo pruebas en una librería dinámica test.so (compilado a partir de test.c) en Linux a través de la biblioteca unidad de pruebas de python y del pitón unittest llamada tests/test_pwmbasic.py.(Esquema de nombres es un poco monótona, me doy cuenta de que ahora)

~/my/test/path/ 
    tests/ 
     __init__.py 
     test_pwmbasic.py 
    test.c 
    test.so 

quiero depurar lo que está en test.so de estímulo en test_pwmbasic.py. Así que esto es como yo tengo trabajo ...

$ cd ~/my/test/path 
$ gdb $(which python) 
    ... gdb blah ... 
(gdb) b test.c:179 
(gdb) run 
>>> from tests.test_pwmbasic import * 
>>> import unittest 
>>> unittest.main() 
    ... unittest blah ... 
Breakpoint 1, pwmTest_setDutyCycles (dutyCycles=0x7ffff7ece910) at ./test.c:179 
(gdb) print pwm_errorCode 
$1 = PWM_ERROR_NONE 

y ahora quiere casarse con GDB

nota: test.c incluye también ../pwm.c, así que también puede punto de ruptura dentro de esa biblioteca con

(gdb) b pwm.c:123 
Cuestiones relacionadas