分层 ldd(1)

2024-11-07 08:55:00
admin
原创
149
摘要:问题描述:由于使用 Gentoo,经常会发生更新后程序链接到旧版本的库的情况。通常,revdep-rebuild 可以帮助解决该问题,但这次它依赖于 python 库,因此python-updater无法将其拾取。是否有“分层”变体ldd可以向我显示哪个共享库依赖于哪个共享库?大多数情况下,库和可执行文件仅与...

问题描述:

由于使用 Gentoo,经常会发生更新后程序链接到旧版本的库的情况。通常,revdep-rebuild 可以帮助解决该问题,但这次它依赖于 python 库,因此python-updater无法将其拾取。

是否有“分层”变体ldd可以向我显示哪个共享库依赖于哪个共享库?大多数情况下,库和可执行文件仅与少数其他共享库链接,而这些共享库又与少数共享库链接,从而将库依赖关系变成了一个大列表。我想知道我必须使用我升级的另一个库的新版本重建哪个依赖关系。


解决方案 1:

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

的‘分层’版本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

解决方案 2:

如果您正在使用 运行 Portage≥2.2 FEATURES=preserve-libs,那么您几乎不再需要revdep-rebuild更多了,因为旧.so.版本会根据需要进行保留(尽管您仍然需要小心地重建,因为当libA.so.0需要libC.so.0libB.so.0时东西仍然会崩溃libC.so.1,而一些二进制文件需要libA.so.0libB.so.0)。


话虽如此,ldd动态链接器所做的就是像平常一样加载可执行文件或库,但在此过程中打印出一些信息。这是一个递归的“二进制文件需要库需要其他库……”搜索,因为这就是动态链接器所做的。

我目前正在运行 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 块大小] [-i 输入文件] [-o 输出文件] [-svwnf]
       [-c 每次读取块数] [-d 读取间隔延迟因子] [-e 最大坏块数]
       [-p 次数] [-t 测试模式 [-t 测试模式 [...]]]
       设备 [最后一个区块 [第一个区块]]
$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

解决方案 3:

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

您还可以使用它ldd -v查看所有共享库的所有依赖项,但它不会显示层次树。

解决方案 4:

我原本也打算建议使用“readelf -d”,但同时要确保使用 LDFLAGS="-Wl,--as-needed" 进行构建(如果您还没有这样做的话)。这样可以减少您遇到此问题的次数。Portage 2.2 的 retain-libs 很不错,但我认为它之所以被屏蔽主要是因为它 - 它确实存在缺陷。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1109  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   73  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   63  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   71  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   66  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用