分层ldd(1) [英] Hierarchical ldd(1)

查看:142
本文介绍了分层ldd(1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



是否有一个等级变体 ldd ,它向我显示共享库依赖于哪个共享库?大多数情况下,库和可执行文件仅与少数其他共享库链接,而这些共享库又与少数链接,将库依赖关系变为大列表。我想知道我需要用我升级的另一个库的新版本来重建哪个依赖项。

解决方案

如果你正在运行Portage≥ 2.2和 FEATURES = preserve-libs ,您应该很少再需要 revdep-rebuild code> .so。 vers将会根据需要保留(尽管你仍然需要仔细重建,因为当 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 [... ]]]
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)

版本信息:
/ 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(需要)共享库:[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 的动态链接器。


Due to using Gentoo, it often happens that after an update programs are linked against old versions of libraries. Normally, revdep-rebuild helps resolving that, but this time it's a dependency on a python library, and python-updater won't pick it up.

Is there a "hierarchical" variant of ldd which shows me what shared library depends on which another shared library? Most of the time libraries and executables are linked only against a handful of other shared libraries, which in turn were linked against a handful, turning the library dependency into a big list. I want to know which dependency I've got to rebuild with the new version of another library that I upgraded.

解决方案

If you are running Portage≥2.2 with FEATURES=preserve-libs, you should rarely ever need revdep-rebuild anymore as old .so.vers will be preserved as needed (though you still need to rebuild carefully, as stuff still goes kaboom when libA.so.0 wants libC.so.0 and libB.so.0 wants libC.so.1 and some binary wants both libA.so.0 and libB.so.0).


That being said, what ldd does is to get the dynamic linker to do load the executable or library as it usually would, but print out some info along the way. This is a recursive "binary needs library needs other library&hellip" search, because that's what the dynamic linker does.

I'm currently running Linux/ppc32; on Linux/x86, the dynamic linker is usually /lib/ld-linux.so.2, and on Linux/x86_64, the dynamic linker is usually /lib/ld-linux-x86-64.so.2. Here, I call it directly just to hammer in the point that all ldd is nothing more than a shell script that calls upon the dynamic linker to perform its magic.

$ /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 doesn't list libpthread.so.0 as a library dependency, but it gets pulled in by libcom_err.so.2.

Is your problem that ldd doesn't output a nice-looking dependency tree? Use 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


If you want, you can read the ELF headers directly instead of depending on the dynamic linker.

$ 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]

You can also man ld.so for other cute tricks you can play with glibc's dynamic linker.

这篇关于分层ldd(1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆