ldd
est un bon moyen simple de vérifier les bibliothèques partagées qu'un exécutable donné utilise ou utilisera. Cependant, cela ne fonctionne pas toujours comme prévu. Par exemple, voir l'extrait shell suivante qui montre comment il « ne » pour fonder la libreadline « dépendance » dans le binaire pythonvérification des bibliothèques partagées pour les chargeurs non par défaut
J'ai essayé beaucoup d'autres distributions, mais je copie de Tikanga
$ lsb_release -a
LSB Version: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5.6 (Tikanga)
Release: 5.6
Codename: Tikanga
Voir ce que ldd
fait sur le python
installé par défaut (à partir des dépôts officiels).
$ which python
/usr/bin/python
$ ldd `which python`
libpython2.4.so.1.0 => /usr/lib64/libpython2.4.so.1.0 (0x00000030e6200000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e0e00000)
libdl.so.2 => /lib64/libdl.so.2 (0x00000030e0a00000)
libutil.so.1 => /lib64/libutil.so.1 (0x00000030ee800000)
libm.so.6 => /lib64/libm.so.6 (0x00000030e0600000)
libc.so.6 => /lib64/libc.so.6 (0x00000030e0200000)
/lib64/ld-linux-x86-64.so.2 (0x00000030dfe00000)
$ ldd `which python` | grep readline
$
Rien trouvé à propos de readline. Maintenant, je sais par l'utilisation interactive que ce binaire a des fonctionnalités réelles, alors n'essayons pas de voir d'où il vient.
$ python &
[1] 21003
$ Python 2.4.3 (#1, Dec 10 2010, 17:24:35)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-50)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
[1]+ Stopped python
Commencer une session interactive de python en arrière-plan (pid 21003)
$ lsof -p 21003
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
python 21003 ddvento cwd DIR 0,33 16384 164304 /glade/home/ddvento/loader-test
python 21003 ddvento rtd DIR 8,3 4096 2/
python 21003 ddvento txt REG 8,3 8304 6813419 /usr/bin/python
python 21003 ddvento mem REG 8,3 143600 8699326 /lib64/ld-2.5.so
python 21003 ddvento mem REG 8,3 1722304 8699327 /lib64/libc-2.5.so
python 21003 ddvento mem REG 8,3 615136 8699490 /lib64/libm-2.5.so
python 21003 ddvento mem REG 8,3 23360 8699458 /lib64/libdl-2.5.so
python 21003 ddvento mem REG 8,3 145824 8699445 /lib64/libpthread-2.5.so
python 21003 ddvento mem REG 8,3 247544 6821551 /usr/lib64/libreadline.so.5.1
python 21003 ddvento mem REG 8,3 15840 8699446 /lib64/libtermcap.so.2.0.8
python 21003 ddvento mem REG 8,3 1244792 6833317 /usr/lib64/libpython2.4.so.1.0
python 21003 ddvento mem REG 8,3 18152 8699626 /lib64/libutil-2.5.so
python 21003 ddvento mem REG 8,3 56446448 6832889 /usr/lib/locale/locale-archive
python 21003 ddvento mem REG 8,3 21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so
python 21003 ddvento mem REG 8,3 25464 6901074 /usr/lib64/gconv/gconv-modules.cache
python 21003 ddvento 0u CHR 136,1 3 /dev/pts/1
python 21003 ddvento 1u CHR 136,1 3 /dev/pts/1
python 21003 ddvento 2u CHR 136,1 3 /dev/pts/1
$ lsof -p 21003 | grep readline
python 21003 ddvento mem REG 8,3 247544 6821551 /usr/lib64/libreadline.so.5.1
python 21003 ddvento mem REG 8,3 21808 6965997 /usr/lib64/python2.4/lib-dynload/readline.so
Bingo! Ici c'est readline!
Cependant, cette technique ne fonctionne que lorsque la bibliothèque est effectivement chargée, donc par exemple, il ne trouve pas /usr/lib64/libtcl8.4.so
jusqu'à ce que le processus de python ne fonctionne pas quelque chose comme from Tkinter import *
J'ai donc deux questions:
Je crois que le problème avec
ldd
est qu'il suppose l'utilisation du chargeur standard, alors que très probablement python utilise son propre chargeur spécial (de sorte que vous ne devez pas relier l'exécutable chaque fois que vous installez un nouveau module python n'est pas pur python mais a un certain c/C++/fortran code). Est-ce correct? De toute évidence, si un exécutable utilise son propre chargeur, il n'y a pas de réponse évidente à la question «comment trouver toutes les bibliothèques possibles que cet exécutable peut charger»: cela dépend de ce que fait le chargeur. Mais existe-t-il un moyen de savoir quelles bibliothèques peuvent être chargées par python?
PS: lié à 1. Si vous êtes à l'atterrissage sur cette question que vous devriez déjà savoir ce qui suit, mais si vous ne devriez pas: voir comment simple est de complètement gâcher ldd
sortie (Messing it up uniquement en partie est un peu plus difficile):
$ cat hello.c
#include <stdio.h>
int main() {
printf("Hello world.\n");
return 0;
}
$ gcc -static hello.c -o loader
$ gcc -Wl,--dynamic-linker,./loader hello.c -o hello
$ ./hello
Hello world.
$ ldd ./hello
Hello world.
Ok, merci, j'ai légèrement modifié votre réponse et l'ai accepté. – Davide