分层ldd(1)

Ast*_*tro 38 linux linker gcc gentoo ldd

由于使用Gentoo,经常会在更新程序与旧版本的库链接之后发生.通常,revdep-rebuild有助于解决这个问题,但这次它依赖于python库,并且python-updater不会接受它.

是否有"分层"变体ldd向我展示了共享库依赖于哪个共享库?大多数情况下,库和可执行文件仅与少数其他共享库链接,而这些共享库又与少数几个库链接,将库依赖项转换为大型列表.我想知道我使用我升级的另一个库的新版本重建哪个依赖项.

Mic*_*rny 74

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

'层次'版本lddlddtree(来自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
Run Code Online (Sandbox Code Playgroud)

  • 先生,你是我的英雄.感谢您提及`lddtree`,我一直在寻找这样的工具. (3认同)
  • lddtree 在这里:https://github.com/gentoo/pax-utils/blob/master/lddtree.py (https://github.com/ncopa/lddtree 上还有一个用 sh 而不是 python 编写的分支) 。 (2认同)

eph*_*ent 20

如果您正在使用运行Portage≥2.2 FEATURES=preserve-libs,你几乎很少需要revdep-rebuild了,因为老.so.VERS将被保留为需要(虽然你仍然需要仔细重建,当作为东西还是那张KABOOM 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
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

/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)

        Version information:
        /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 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]

您还可以man ld.so使用其他可爱的技巧,您可以使用glibc动态链接器.


Jon*_*ely 10

我需要这样的东西,所以我写道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)