分层 ldd(1)

2024-11-07 08:55:00
admin
原创
31
摘要:问题描述:由于使用 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 很不错,但我认为它之所以被屏蔽主要是因为它 - 它确实存在缺陷。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用