如何找到二进制文件的哪个部分需要某个版本的某个依赖项?

Posted

技术标签:

【中文标题】如何找到二进制文件的哪个部分需要某个版本的某个依赖项?【英文标题】:How to find which part of a binary requires a certain version of a certain dependency? 【发布时间】:2022-01-17 11:31:23 【问题描述】:

我正在将一些继承的代码编译到 linux 平台上。当我尝试运行它时,我得到一个库版本控制错误:

[aardvark@aardvark-burrow /data/users/aardvark/project-source]  /data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay
/data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by /data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay)

首先,谁在乎我有 GLIBC_2.28,而不是 2.29,他们为什么在乎?它是传递给构建最终可执行文件 (fcv_replay) 的编译标志,还是它的众多依赖项之一?我怎么知道?我基本上想知道在我没有创建的大型复杂构建系统中寻找什么。

这是另一个查询的结果:

[aardvark@ /data/users/aardvark/project-source] ldd /data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay
/data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by /data/users/aardvark/project-source/buck-out/gen/arvr/projects/viper/applications/replay/fcv_replay)
        linux-vdso.so.1 (0x00007ffe84592000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe4daefd000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fe4dab7b000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fe4da977000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fe4da5b2000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe4db11d000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe4da39a000)

【问题讨论】:

【参考方案1】:

您的应用程序 fcv_replay 已在较新的 Linux 发行版(或新的工具链)上编译,并且正在使用 libm 库中的一些新功能,这些新功能在您当前的发行版中缺失。

您可以通过检查反汇编来查看可执行文件的哪个部分导致了问题:

$ objdump -dr /bin/nautilus | grep -C5 GLIBC_2.29 | head
000000000004a430 <pow@plt>:
   4a430:   f3 0f 1e fa             endbr64 
   4a434:   f2 ff 25 45 1e 16 00    bnd jmpq *0x161e45(%rip)        # 1ac280 <pow@GLIBC_2.29>
   4a43b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
...

最好的解决方案是在最旧的发行版上重建 fcv_replay 以避免依赖于新版本的 libc。

【讨论】:

听起来不错,只是我在同一个 VM 上编译和运行。 FWIW,这是 'uname -a' spew,它是一个新的 CentOS 虚拟机。 Linux aardvark-burrow.zoo.com 5.6.13-0_fbk19_hardened_6064_gabfd136bb69a #1 SMP Fri Oct 22 10:57:22 PDT 2021 x86_64 x86_64 x86_64 GNU/Linux @AdventurousAardvark 这很有趣,你能链接到-Wl,--verbose 并检查链接期间使用了哪个libm.so.6 吗?我认为它不是 /lib64/libm.so.6 对你是: grepping 日志出现:` 11981:ld.lld: ./arvr/third-party/toolchains/platform009/build/glibc/lib/libm.so.6 ` 它有意义的是,我的二进制文件所依赖的一些库会链接到那里的东西。但是还有另一个谜团 - 探测 libm.so.6,似乎指向正确的 libc.so.6 文件:` [aardvark@aardvark.burrow.zoo ~/fbsource] ldd ./arvr/third-party/ toolchains/platform009/build/glibc/lib/libm.so.6 libc.so.6 => /lib64/libc.so.6 (0x00007f15587b9000) /lib64/ld-linux-x86-64.so.2 (0x00007f1558b7e000) ` 正在运行:objdump -dr ./arvr/third-party/toolchains/platform009/build/glibc/lib/libm.so.6 | grep GLIBC_2\.2[0-9]+。获得(修剪重复行):10fba: 72 04 jb 10fc0 &lt;lgammal@@GLIBC_2.23+0x30&gt;. 41ac8: 73 06 jae 41ad0 &lt;log@@GLIBC_2.29+0x10&gt;. 。不确定发生了什么,但看起来一个数学库(log、pow 等)与 2.29 相关联,而另一个与 2.23 相关联?科莫埃斯塔? "探测 libm.so.6,似乎指向正确的 libc.so.6 文件" - 在您的默认环境中是但在链接期间很可能是另一个 libc.so.6(来自 @987654332 @) 由于-L 编译器标志而被拾取。

以上是关于如何找到二进制文件的哪个部分需要某个版本的某个依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

Android 查看项目的依赖信息以及某个版本的组件是哪个依赖库里的正确姿势

经验一如何整理出某个页面的插件或者别的!(老大:张国辉)

12fabric node sdk1.4.8发现某个peer加入的所有通道

确定哪个版本的 OpenCV

eclipse如何快速查找某个类

安卓7.0版本怎么用SD卡