分层 ldd(1)
- 2024-11-07 08:55:00
- admin 原创
- 31
问题描述:
由于使用 Gentoo,经常会发生更新后程序链接到旧版本的库的情况。通常,revdep-rebuild 可以帮助解决该问题,但这次它依赖于 python 库,因此python-updater
无法将其拾取。
是否有“分层”变体ldd
可以向我显示哪个共享库依赖于哪个共享库?大多数情况下,库和可执行文件仅与少数其他共享库链接,而这些共享库又与少数共享库链接,从而将库依赖关系变成了一个大列表。我想知道我必须使用我升级的另一个库的新版本重建哪个依赖关系。
解决方案 1:
我看到许多有趣的细节,但没有直接回答所提的问题。
的‘分层’版本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
解决方案 2:
如果您正在使用 运行 Portage≥2.2 FEATURES=preserve-libs
,那么您几乎不再需要revdep-rebuild
更多了,因为旧.so.
版本会根据需要进行保留(尽管您仍然需要小心地重建,因为当libA.so.0
需要libC.so.0
和libB.so.0
时东西仍然会崩溃libC.so.1
,而一些二进制文件需要libA.so.0
和libB.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 很不错,但我认为它之所以被屏蔽主要是因为它 - 它确实存在缺陷。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件