【问题标题】:Protect against linking multiple versions of a shared library防止链接共享库的多个版本
【发布时间】:2019-01-22 03:21:50
【问题描述】:

当您使用semantic versioning 时,从libfoo.so.23 切换到libfoo.so.24 意味着libfoo 的API 以向后不兼容的方式更改。

因此,不得同时链接libfoo.so.23libfoo.so.24

例子:

现状:

  • 可执行的myexe 链接到libfoo.so.23libbar.so.1
  • libbar.so.1 本身也链接到 libfoo.so.23

错误更改:

  • libbar.so.1 升级到 libfoo.so.24 而不增加其主要版本号

因此,当调用 myexe 时,动态链接器现在会加载 libfoo.so.23libfoo.so.24(参见 ldd 输出),从而导致一组函数使用来自 libfoo 的向后不兼容的符号。

如何防范此类错误?

这意味着:我如何告诉链接器在这种情况下(在构建时和运行时)出错?

在 Linux 上,链接器只是在构建时发出警告:

/usr/bin/ld: warning: libfoo.so.24, needed by libbar.so.1, 
    may conflict with libfoo.so.23

是否可以将其变成链接错误?

(此警告不会在运行时出现。)

其他 Unices 上的其他链接器甚至不会在构建时发出警告。

使用在库加载期间执行的构造函数可以在运行时检测到此类库版本不匹配。例如:

#include <stdio.h>
#include <stdlib.h>

#define FOO_VERSION 23    
int foo_version() { return FOO_VERSION; }

static void cons() __attribute__((constructor));
static void cons()
{
  fprintf(stderr, "constructing foo (%d)\n", foo_version());
  if (foo_version() != FOO_VERSION) {
    fprintf(stderr, "foo.c: FOO_VERSION %d != foo_version() %d\n",
        FOO_VERSION, foo_version());
    exit(1);
  }
}

但我希望在构建时/运行时出现链接器错误。理想情况下,也会出现在 ldd 中(作为错误)。

【问题讨论】:

    标签: linker shared-libraries ld elf


    【解决方案1】:

    是否可以将其变成链接错误?

    GNU ld 和 Gold have:

       --fatal-warnings
       --no-fatal-warnings
           Treat all warnings as errors.  The default behaviour can be
           restored with the option --no-fatal-warnings.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 2012-07-14
      • 2016-10-05
      • 2011-03-15
      相关资源
      最近更新 更多