6

我写了一个包含几个不兼容版本的共享库。我更改了 SONAME,因此它们被称为:

  • lib_mylib.so.1.0.0(旧库)
  • lib_mylib.so.2.0.0

有一些函数只在 mylib.so.1 中,其他只在 mylib.so.2 中,许多函数很常见(但有几个改变了参数数量)

而且我担心可以将 mylib 的两个版本链接到单个应用程序中,例如当应用程序本身很大并且包含许多库时。当应用程序部分重建时,可能会出现这样的情况:

  • 应用
  • app_lib1.so(使用 mylib.so.1 构建 - 我的 lib 的第一个版本)
  • app_lib2.so(用 mylib.so.2 重建 - 第二个版本)

我已经看到加载了两个版本的应用程序(都ldd报告了)。

那么,是否可以在 mylib.so.2 中添加一些检查代码来检测是否已经加载了两个版本的库并且它们具有冲突的 ABI/接口。(我不能修改 lib_mylib.so.1 来添加一些东西)

4

2 回答 2

3

您可以修改版本 2 库以dlsym(3)在初始化期间解析某些版本 1 特定符号 ( ) 并在找到时崩溃。

例子:

extern __attribute__((constructor)) void _version_check2()
{
    if (dlsym(RTLD_DEFAULT, "version_1_function"))
        abort();
}

一个更优雅的解决方案是让版本 2 库模仿版本 1 的行为,但这会引入遗留代码。

编辑

为了未来的证明,您还可以引入静态版本变量,所有函数调用都会检查它是否与当前版本匹配。然后在未来的版本中,您只需要更改该变量的值并在不匹配时崩溃。

编辑 2

您还可以在每个版本 2 函数上调用此函数,以便在加载版本 1 时,您的应用程序迟早会崩溃。

于 2013-10-16T07:37:53.223 回答
1

您可以解析/proc/self/maps以获取当前加载的对象的列表。

于 2013-10-10T00:24:57.690 回答