由于使用 Gentoo,经常会发生更新程序与旧版本库链接后的情况。通常, revdep-rebuild 有助于解决这个问题,但这次它依赖于 python 库,并且python-updater
不会选择它。
是否有一个“分层”变体ldd
向我展示了哪个共享库依赖于另一个共享库?大多数情况下,库和可执行文件仅与少数几个其他共享库链接,而这些共享库又与少数几个共享库链接,从而将库依赖关系变成一个大列表。我想知道我必须用我升级的另一个库的新版本重建哪个依赖项。
我看到了许多有趣的细节,但没有直接回答所提出的问题。
的“分层”版本ldd
是lddtree
(来自app-misc/pax-utils
):
$ lddtree /usr/bin/xmllint
xmllint => /usr/bin/xmllint (interpreter => /lib64/ld-linux-x86-64.so.2)
libreadline.so.6 => /lib64/libreadline.so.6
libncurses.so.5 => /lib64/libncurses.so.5
libdl.so.2 => /lib64/libdl.so.2
libxml2.so.2 => /usr/lib64/libxml2.so.2
libicui18n.so.49 => /usr/lib64/libicui18n.so.49
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libstdc++.so.6
ld-linux.so.2 => /lib64/ld-linux.so.2
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libgcc_s.so.1
libicuuc.so.49 => /usr/lib64/libicuuc.so.49
libicudata.so.49 => /usr/lib64/libicudata.so.49
libz.so.1 => /lib64/libz.so.1
liblzma.so.5 => /usr/lib64/liblzma.so.5
libm.so.6 => /lib64/libm.so.6
libpthread.so.0 => /lib64/libpthread.so.0
libc.so.6 => /lib64/libc.so.6
如果你使用 运行 Portage≥2.2 ,FEATURES=preserve-libs
你应该很少需要revdep-rebuild
了,因为旧版本会.so.
根据需要保留(尽管你仍然需要仔细重建,因为当需要和需要时,东西仍然会变得很糟糕,而一些二进制文件同时需要和)。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_64 上,动态链接器通常是/lib/ld-linux-x86-64.so.2
. 在这里,我直接调用它只是为了强调一点,一切ldd
只不过是一个调用动态链接器来执行其魔法的 shell 脚本。
$ /lib/ld.so.1 /sbin/badblocks 用法:/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 [...]]] 设备 [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
/sbin/badblocks
没有libpthread.so.0
列为库依赖项,但它被libcom_err.so.2
.
您的问题是ldd
没有输出漂亮的依赖树吗?使用ldd -v
.
$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=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 (0x201f9000) 版本信息: /sbin/坏块: libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 /lib/libext2fs.so.2: libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 libc.so.6 (GLIBC_2.3) => /lib/libc.so.6 libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 /lib/libcom_err.so.2: ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0 libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0 libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 /lib/libc.so.6: ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 /lib/libpthread.so.0: ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 ld.so.1 (GLIBC_2.1) => /lib/ld.so.1 ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6 libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6 libc.so.6 (GLIBC_2.0) => /lib/libc.so.6
如果需要,您可以直接读取 ELF 标头,而不是依赖于动态链接器。
$ 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]
您还可以使用的动态链接器man ld.so
来玩其他可爱的技巧。glibc
我需要这样的东西,所以我写了tldd
,这里显示了它自己的库依赖项:
$ ./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)
我还建议使用“readelf -d”,但如果您还没有使用 LDFLAGS="-Wl,--as-needed",请确保您使用它进行构建。这将使您减少遇到此问题的频率。Portage 2.2 的 preserve-libs 很好,但我认为它被掩盖主要是因为它——它确实有缺陷。