Comprobar bibliotecas compartidas para los cargadores no predeterminados
ldd
es una buena forma sencilla de verificar las bibliotecas compartidas que un ejecutable determinado está utilizando o utilizará. Sin embargo, no siempre funciona como se esperaba. Por ejemplo, vea el siguiente fragmento de shell que muestra cómo "falla" encontrar la "dependencia" de libreadline en el binario de python
He intentado muchas otras distribuciones, pero estoy copiando desde Tikanga
<code>$ 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 </code>
Mira quéldd
lo hace en el predeterminado instaladopython
(De repositorios oficiales).
<code>$ 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 $ </code>
No se ha encontrado nada sobre readline. Ahora sé por el uso interactivo que este binario tiene una funcionalidad real, así que no intente ver de dónde viene.
<code>$ 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 </code>
Comenzó una sesión interactiva de python en segundo plano (pid 21003)
<code>$ 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 </code>
¡Bingo! ¡Aquí está readline!
Sin embargo, esta técnica funciona solo cuando la biblioteca está cargada efectivamente, por lo que, por ejemplo, no encuentra/usr/lib64/libtcl8.4.so
hasta que el proceso de python no se ejecuta algo comofrom Tkinter import *
Así que tengo dos preguntas:
Creo que el problema conldd
es que asume el uso del cargador estándar, mientras que es muy probable que Python esté usando su propio cargador especial (de modo que no tenga que volver a vincular el ejecutable cada vez que instale un nuevo módulo de Python que no sea Python puro sino que tenga algo de C). / c ++ / código fortran). ¿Es esto correcto?
Claramente, si un ejecutable está utilizando su propio cargador, no hay una respuesta obvia a la pregunta "cómo encontrar todas las bibliotecas posibles que este ejecutable puede cargar": depende de lo que haga el cargador. Pero, ¿hay alguna manera de averiguar qué bibliotecas puede cargar Python?
PD: relacionado con 1. Si te estás dirigiendo a esta pregunta, ya deberías saber lo siguiente, pero si no, deberías: ver qué simple es desordenar completamenteldd
salida (arruinarlo solo parcialmente es un poco más difícil):
<code>$ 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. </code>