2009-04-29 6 views
32

Quelqu'un peut-il me dire comment faire du débogage à l'exécution sur les bibliothèques partagées?Comment exécuter les bibliothèques partagées de débogage?

J'ai besoin de déboguer une fonction dans ma bibliothèque partagée, mais elle est appelée par un autre programme. Comment puis-je faire quelque chose comme dbx avec des bibliothèques partagées?

J'utilise dbx sous AIX. est gdb mieux que dbx pour ce que j'essaie de faire.

Répondre

28

Vous avez juste besoin d'appeler gdb avec l'exécutable (peu importe si c'est le vôtre ou un tiers). Voici un exemple où je débogue la commande ls et définit un point d'arrêt dans la bibliothèque c (partagée). Cet exemple utilise gdb 6.8 qui prend en charge différée (en attente), qui fait des points d'arrêt aussi facile:

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) 

Comme vous pouvez le voir gdb gère automatiquement tous les fils utilisés par l'exécutable. Vous n'avez rien à faire de spécial pour les threads. Le point d'arrêt fonctionnera dans n'importe quel thread.

Alternativement, si vous souhaitez joindre le débogueur à une application déjà en cours (j'utilise tail -f/tmp/ttt ici comme exemple):

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 utilisé dbx sur AIX. si vous dites que gdb peut le faire avec des applications filetées ..puis dbx suce beaucoup de temps .. et j'ai été un imbécile total pour l'utiliser tout ce temps. –

+0

Sad gdb ne fonctionne pas correctement sur AIX ... AIX suce .. –

+0

Je ne sais pas dbx, mais il devrait avoir des caractéristiques similaires – lothar

9

Normalement, la procédure de débogage d'une bibliothèque partagée est sensiblement la même que pour déboguer un exécutable. La principale différence est que vous ne pouvez pas définir un point d'arrêt tant que la bibliothèque partagée n'est pas chargée en mémoire. Vous attachez le débogueur à l'exécutable principal.

Si vous déboguez une application qui ne vous appartient pas mais qui utilise votre module dans une architecture de plug-in, vous utilisez toujours la même méthode. Assurez-vous (comme toujours) que vous disposez des informations de débogage disponibles pour votre bibliothèque partagée. Dans Windows, vous générez un fichier .pdb. Avec gcc, je pense que vous spécifiez un indicateur de compilation spécial (-g?) Pour vous assurer que les informations de débogage sont fournies. Vous attachez le débogueur à l'application tierce.

+0

que si l'exécutable principal n'est pas le mien et son tiers de certains ... mais im écrit un module qui sera utilisé par la 3ème partie ... Comment puis-vous déboguer alors? –

+0

Vous démarrez toujours l'exécutable (ou attachez-le à un processus) avec gdb. Une fois votre bibliothèque chargée, gdb peut y définir des points d'arrêt sans problème. – lothar

+0

Mais quand vous définissez un point d'arrêt dans votre code lib partagé et si l'exécutable principal l'appelle, l'exécutable principal ne sera-t-il pas bloqué? –

1

Je me souviens avoir testé des bibliothèques partagées en créant une application fictive qui l'utilisait. Si vous êtes prêt à faire beaucoup de travail, vous pouvez créer une deuxième bibliothèque partagée factice qui collecte uniquement des informations sur la façon dont la bibliothèque est utilisée par l'application tierce, puis demandez à votre application fictive de rejouer ces informations.

Bien sûr, ne doutez jamais de la puissance des appels printf et fprintf bien placés.

0

Vous pouvez essayer de compiler et de lier la bibliothèque de façon statique pour la déboguer.
Si votre bogue apparaît seulement quand il est compilé en tant que partagé, cela pourrait vous donner quelques indices.

1

Il a été longtemps que je J'ai dû utiliser dbx sur AIX, et j'ai aussi fait face à ce problème. L'installation de gdb n'était pas une option pour moi.

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

Un autre exemple encore à la réponse de lothar:

Je l'exécution des tests sur une bibliothèque dynamique test.so (compilé à partir test.c) sous Linux en utilisant python et la bibliothèque des tests unitaires de python unittest appelé tests/test_pwmbasic.py.(Schéma de nommage est un peu monotone, je me rends compte que maintenant)

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

Je veux déboguer ce qui est dans test.so de stimulus test_pwmbasic.py. Voilà donc comment je l'ai eu à travailler ...

$ 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 

et maintenant je veux me marier avec gdb

Note: test.c comprend également ../pwm.c, donc je peux aussi dans ce point d'arrêt bibliothèque

(gdb) b pwm.c:123 
Questions connexes