由于使用 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.0libC.so.0libB.so.0libC.so.1libA.so.0libB.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 很好,但我认为它被掩盖主要是因为它——它确实有缺陷。