【发布时间】:2012-05-02 10:46:15
【问题描述】:
ldd 是检查给定可执行文件正在或将要使用的共享库的好方法。但是,它并不总是按预期工作。例如,请参阅以下 shell sn-p,它演示了如何“失败”在 python 二进制文件中找到 libreadline“依赖项”
我尝试了许多其他发行版,但我是从 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
查看ldd 对默认安装的python 的作用(来自官方存储库)。
$ 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
$
没有找到关于 readline 的信息。现在我从交互式使用中确实知道这个二进制文件确实具有实时功能,所以让我们不要尝试查看它的来源。
$ 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
在后台启动交互式 python 会话 (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
宾果!这里是readline!
但是,这种技术仅在库被有效加载时才有效,例如,直到 python 进程不运行类似 from Tkinter import * 的东西时,它才会找到 /usr/lib64/libtcl8.4.so
所以我有两个问题:
我认为
ldd的问题在于它假定使用标准加载器,而 python 很可能使用它自己的特殊加载器(这样您就不必每次都重新链接可执行文件)安装一个新的 python 模块,它不是纯 python,但有一些 c/c++/fortran 代码)。这是正确的吗?
1234563但是有没有办法找出python可以加载哪些库?
PS:与 1 相关。如果您正在回答这个问题,您应该已经知道以下内容,但如果不知道,您应该:看看完全搞砸 ldd 输出是多么简单(只是部分搞砸是有点困难):
$ 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.
【问题讨论】:
-
您能解释一下您的 Hello World 是如何愚弄
ldd的吗?这里是菜鸟。 -
我在尝试运行
hello时遇到了段错误,尽管loader运行良好。ldd说not a dynamic executable代表loader(预期),而hello给我ldd ./hello linux-vdso.so.1 (0x00007ffe0f5a0000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6257aca000) ./loader => /lib64/ld-linux-x86-64.so.2 (0x00007f62580bd000)。顺便说一句,这是 ubuntu 18.04
标签: linux shared-libraries ldd