分层ldd(1)

由于使用Gentoo,经常发生在更新程序与旧版本的库链接之后。 通常情况下,revdep-rebuild有助于解决这个问题,但是这次它是一个python库的依赖, python-updater不会去捡起它。

是否有一个ldd的“等级”变体,告诉我共享库依赖于哪个共享库? 大多数情况下,库和可执行文件仅与less数其他共享库链接,而这些共享库又与less数几个库链接,从而将库依赖关系变为大列表。 我想知道哪些依赖关系,我已经与我升级的另一个库的新版本重build。

Solutions Collecting From Web of "分层ldd(1)"

如果你使用FEATURES=preserve-libs来运行Portage≥2.2,那么你应该很少再需要使用revdep-rebuild作为旧的.so. 根据需要保留vers(尽管你仍然需要仔细重建,因为当libA.so.0 libC.so.0libB.so.0 libC.so.1 ,还有一些需要libA.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目录/ badblocks:
                 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动态链接器的其他可爱技巧。

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

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 

我需要这样的东西,所以我写了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, – 根据需要”构建,如果你还没有的话。 这会让你不经常碰到这个问题。 Portage 2.2的preserve-libs是不错的,但是我收集它主要是因为它的掩盖 – 它确实有缺陷。