Pregunta

¿Puede alguien decirme cómo hacer la depuración en tiempo de ejecución en bibliotecas compartidas?

Necesito en tiempo de ejecución-depurar una funció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 para lo que estoy tratando de hacer?

¿Fue útil?

Solución

Solo necesitas llamar a gdb con el ejecutable (no importa si es tuyo o de un tercero). Aquí hay un ejemplo en el que depuro el comando ls y establezco un punto de interrupción en la (compartida) c library . Este ejemplo utiliza gdb 6.8 que admite puntos de interrupción diferidos (pendientes), lo que facilita esta tarea:

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 puede ver, gdb administra automáticamente todos los subprocesos utilizados por el ejecutable. No tienes que hacer nada especial para los hilos allí. El punto de interrupción funcionará en cualquier hilo.

Alternativamente, si desea adjuntar el depurador a una aplicación que ya esté en ejecución (uso tail -f / tmp / ttt aquí como 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)

Otros consejos

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

Si está depurando una aplicación que no le pertenece, pero está usando su módulo en una arquitectura de complementos, todavía usa el mismo método. Asegúrese (como siempre) de que tiene información de depuración disponible para su biblioteca compartida. En Windows, generarías un archivo .pdb. Con gcc, creo que especifica un indicador de compilador especial (-g?) Para garantizar que se proporcione información de depuración. Adjuntarás el depurador a la aplicación de terceros.

Otro ejemplo adicional a la respuesta de Lothar:

Estoy ejecutando pruebas en una biblioteca dinámica test.so (compilada de test.c ) en Linux usando python y la unidad de python -testing library unittest llamado tests / test_pwmbasic.py . (El esquema de nombres es un poco monótono, 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 del estímulo en test_pwmbasic.py . Así es como lo hice funcionar ...

$ 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 quiero casarme con gdb

nota: test.c también incluye ../pwm.c , por lo que también puedo romper puntos dentro de esa biblioteca con

(gdb) b pwm.c:123

Recuerdo haber probado bibliotecas compartidas creando una aplicación simulada que la usaba. Si está dispuesto a hacer mucho trabajo, puede crear una segunda biblioteca compartida simulada que simplemente recopila información sobre cómo la biblioteca está siendo utilizada por la aplicación de terceros, y luego hacer que su aplicación simulada reproduzca esa información.

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

Hace mucho tiempo que tuve que usar dbx en AIX, y también enfrenté este problema. 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

Puedes intentar compilar y vincular la biblioteca de forma estática para depurarla.
Si tu error solo aparece cuando se compila como compartido, eso podría darte algunas pistas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top