linux - Hexeditted 共享库“未找到版本 x.so”错误
问题描述
我的库 A 依赖于外部库 B。当我在 A.so 上使用 ld 时,我看到 B 链接为 B.so.10,但在我的计算机上,链接是:
B.so -> B.so.10
B.so.10 -> B.so.10.5
我试图创建一个指向 JUST B.so 的链接,并使用符号链接来加载要加载的版本。我对 A.so 进行了十六进制编辑,并用 B.so 替换了 B.so.10 的所有发现,并且 ld 链接它就好了,但是当我尝试 dlopen A.so 时,它说:'加载 A.so 时出错:版本 B。所以找不到'我已经阅读了有关符号版本控制等的信息,但老实说,不知道在哪里寻找会导致问题的原因?
我检查了 readelf 并将未编辑的版本与我的进行了比较,除了 SO 名称之外,我在差异中看不到任何东西。Elfedit 也不起作用,只是将二进制文件变成了垃圾数据。
解决方案
如果你运行readelf -V B.so
,你可能会发现它没有定义version B.so
,但确实定义了 version B.so.10
。
通过将所有B.so.10
字符串替换为依赖于版本而不是过去依赖B.so
的运行时加载器的状态。A.so
B.so
B.so.10
由于在运行时不存在这样的版本,加载程序正确地抱怨。
我检查了 readelf 并将未编辑的版本与我的进行了比较,除了 SO 名称之外,我在差异中看不到任何东西。
再检查一遍。特别是,这样做:
diff <(readelf -V A.so.orig) <(readelf -V A.so)
您应该 在那里看到一些差异。
我试图创建一个指向 JUST B.so 的链接,并使用符号链接来加载要加载的版本。
您似乎有一个XY 问题。你真正想要达到什么目的?
更新:
最初的问题是我试图让我的软件 CUDA 版本不可知。...我不能把这个二进制文件放在另一个具有不同 cufft 版本的系统上,因为 cufft 链接到特定版本,即使 ABI 并没有永远改变。
啊,你确实有一个 XY 问题。
实际上,您不能推断ABI没有更改,除非您验证该ABI中可能使用的每个结构都没有更改(这与验证API没有更改不同,您可能已经这样做了)。
如果您成功修补了版本,最终结果可能是在具有不同版本 CUFFT 的系统上发生神秘的崩溃。
如果你幸运的话,崩溃会快速且可重复地发生。如果您不走运,它将很少发生并且看起来完全神秘且无关,只会在某些系统上,仅在某些客户机器上,仅在您对库进行完全不相关的更改后才会发生,等等。
TL;DR:你正在为自己的巨大痛苦做好准备。只是不要这样做。
推荐阅读
- r - 怎么可能每年分别取平均值?
- java - 运行 JMXConnectorFactory.connect 时 JMX 连接不重播
- c++ - 当具有相同值的多个值是 std::vector 的一部分时,std::distance 的计算如何工作
- python - 使用 vaex 从 CSV 转换为 HDF5 时保留日期时间类型
- flutter - Fluter web Navigator 前进按钮
- extjs - 如何在 ExtJs 的标签栏中动态添加 tbar
- pyspark - pyspark 数据框中的正则表达式
- javascript - 为什么我会在我的代码中获得与“不存在”的方法相关的这些错误?
- reactjs - 来自ajax的反应选择选项数据
- android - 在 Flutter 列中拆分子数组