Linux 分层ldd(1)

Linux 分层ldd(1),linux,gcc,linker,gentoo,ldd,Linux,Gcc,Linker,Gentoo,Ldd,由于使用Gentoo,在更新程序后,经常会链接到库的旧版本。通常,revdep rebuild有助于解决这个问题,但这次它依赖于python库,python updater将无法获取它 是否有ldd的“分层”变体向我显示了哪个共享库依赖于哪个其他共享库?大多数情况下,库和可执行文件只针对少数几个其他共享库进行链接,而这些共享库又针对少数共享库进行链接,从而将库依赖关系变成一个大列表。我想知道我必须用我升级的另一个库的新版本重建哪个依赖项。如果您正在运行Portage≥2.2使用FEATURES=

由于使用Gentoo,在更新程序后,经常会链接到库的旧版本。通常,revdep rebuild有助于解决这个问题,但这次它依赖于python库,
python updater
将无法获取它


是否有
ldd
的“分层”变体向我显示了哪个共享库依赖于哪个其他共享库?大多数情况下,库和可执行文件只针对少数几个其他共享库进行链接,而这些共享库又针对少数共享库进行链接,从而将库依赖关系变成一个大列表。我想知道我必须用我升级的另一个库的新版本重建哪个依赖项。

如果您正在运行Portage≥2.2使用
FEATURES=preserve libs
,您应该很少再需要
revdep rebuild
作为旧的
。因此,
版本将根据需要保留(尽管您仍然需要仔细地重建,因为当
libA.so.0
想要
libC.so.0
libB.so.0
想要
libC.so.1
和一些二进制文件既想要
libA.so.0
又想要
libB.so.0
)时,内容仍然会出错)


也就是说,
ldd
所做的是让动态链接器像通常那样加载可执行文件或库,但同时打印出一些信息。这是一个递归的“二进制需要库需要其他库&hellip”搜索,因为动态链接器就是这样做的

我目前正在运行Linux/ppc32;在Linux/x86上,动态链接器通常是
/lib/ld-Linux.so.2
,在Linux/x86\u 64上,动态链接器通常是
/lib/ld-Linux-x86-64.so.2
。在这里,我直接调用它只是为了强调,所有
ldd
都不过是调用动态链接器的shell脚本链接器来执行它的魔术

$ /lib/ld.so.1 /sbin/badblocks Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf] [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks] [-p num_passes] [-t test_pattern [-t test_pattern [...]]] device [last_block [first_block]] $ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks linux-vdso32.so.1 => (0x00100000) libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000) libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000) libc.so.6 => /lib/libc.so.6 (0x0fdfa000) libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000) /lib/ld.so.1 (0x48000000) $ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2 linux-vdso32.so.1 => (0x00100000) libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000) libc.so.6 => /lib/libc.so.6 (0x6fe18000) /lib/ld.so.1 (0x203ba000) $ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2 /lib/libcom_err.so.2
如果需要,可以直接读取ELF头,而不依赖于动态链接器

$ readelf -d /sbin/badblocks | grep NEEDED 0x00000001 (NEEDED) Shared library: [libext2fs.so.2] 0x00000001 (NEEDED) Shared library: [libcom_err.so.2] 0x00000001 (NEEDED) Shared library: [libc.so.6] $ readelf -d /lib/libcom_err.so.2 | grep NEEDED 0x00000001 (NEEDED) Shared library: [libpthread.so.0] 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x00000001 (NEEDED) Shared library: [ld.so.1] $readelf-d/sbin/badblocks |需要grep 0x00000001(需要)共享库:[libext2fs.so.2] 0x00000001(需要)共享库:[libcom_err.so.2] 0x00000001(需要)共享库:[libc.so.6] $readelf-d/lib/libcom_err.so.2|需要grep 0x00000001(需要)共享库:[libpthread.so.0] 0x00000001(需要)共享库:[libc.so.6] 0x00000001(需要)共享库:[ld.so.1]
您还可以使用glibc的动态链接器玩其他可爱的小把戏。

我还打算建议使用“readelf-d”,但也要确保使用LDFLAGS=“-Wl,--根据需要”进行构建如果您还没有。这将减少您遇到此问题的次数。Portage 2.2的preserve libs很不错,但我认为它被屏蔽主要是因为它-它确实有缺陷。

我看到了许多有趣的细节,但没有直接回答所问问题

$ readelf -d /sbin/badblocks | grep NEEDED 0x00000001 (NEEDED) Shared library: [libext2fs.so.2] 0x00000001 (NEEDED) Shared library: [libcom_err.so.2] 0x00000001 (NEEDED) Shared library: [libc.so.6] $ readelf -d /lib/libcom_err.so.2 | grep NEEDED 0x00000001 (NEEDED) Shared library: [libpthread.so.0] 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x00000001 (NEEDED) Shared library: [ld.so.1]
ldd
的“分层”版本是
lddtree
(来自
app misc/pax utils
):


我需要这样的东西,所以我写道,这里它显示了它自己的库依赖关系:

$ ./tldd ./tldd ./tldd └─libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003687c00000) ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000) │ └─libc.so.6 => /lib64/libc.so.6 (0x0000003684c00000) │ └─ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003684400000) └─libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003686c00000) $./tldd./tldd /tldd └─libstdc++.so.6=>/lib64/libstdc++.so.6(0x0000003687c0000) ├─libm.so.6=>/lib64/libm.so.6(0x0000003685000000) │ └─libc.so.6=>/lib64/libc.so.6(0x0000003684c00000) │ └─ld-linux-x86-64.so.2=>/lib64/ld-linux-x86-64.so.2(0x0000003684400000) └─libgcc_.so.1=>/lib64/libgcc_.so.1(0x0000003686c00000)
现在这些缺陷都很小。当我看到这些缺陷时,我想我应该仔细看看它们,比如一个月前或者什么的:P.
ldd-v
输出的树部分只显示带有版本符号的库。先生,您是我的英雄。感谢您提到
lddtree
,我已经寻找这样的工具很久了。很好第一,我不知道:) $ ./tldd ./tldd ./tldd └─libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003687c00000) ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000) │ └─libc.so.6 => /lib64/libc.so.6 (0x0000003684c00000) │ └─ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003684400000) └─libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003686c00000)