Linux共享库版本匹配

时间:2018-04-26 12:09:26

标签: linux linker shared-libraries glibc

我有两台机器,一台是ubuntu 16.04,安装了libc-2.23。另一个是redhat 7,libc版本是2.17

以下简单程序在ubuntu上编译,可以在redhat 7上运行良好。

#include <stdio.h>
#include <math.h>

int main(int argc, char *argv[])
{
  printf("hello world\n");
  double n = 4;
  printf("%e\n", sqrt(n));
  return 0;
}

但是当我在ubuntu上编译mongodb,并将二进制文件发送到redhat 7时,我收到以下错误。

[zhifan@rhel-2372970 ~]$ ldd mongod
./mongod: /lib64/libm.so.6: version `GLIBC_2.23' not found (required by ./mongod)
        linux-vdso.so.1 =>  (0x00007ffd4313a000)
        libm.so.6 => /lib64/libm.so.6 (0x00007faaf5eb4000)
        librt.so.1 => /lib64/librt.so.1 (0x00007faaf5cac000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007faaf5aa7000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007faaf5891000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007faaf5675000)
        libc.so.6 => /lib64/libc.so.6 (0x00007faaf52b1000)
        /lib64/ld-linux-x86-64.so.2 (0x0000564cf2068000)

所以我的问题是:

  1. 当运行二进制文件时,库加载器如何决定它找到的库(在这种情况下是libc)可以使用吗?
  2. 我确定完全相同版本的mongod(由mongo inc构建)可以与libc-2.17一起运行,但为什么我的构建不能与libc-2.17一起运行?

1 个答案:

答案 0 :(得分:0)

  

当运行二进制文件时,库加载器如何决定它找到的库(在这种情况下为libc)可以使用?

它查找应用程序所需的符号版本。 IFF所有必需的符号都可用,然后可以使用库。

您可以通过运行readelf -V a.out来查看所需的符号。

  

为什么我的构建无法与libc-2.17一起运行

当您将二进制文件与GLIBC-2.23相关联时,可能会使用该版本中的符号定义。与早期版本相比,这些符号具有不同的ABI,因此无法使用早期版本。

为了避免这种情况,你可以在旧系统上 构建(二进制文件在较新的系统上运行就好了 - 它将使用较旧的符号ABI),或者你必须构建Linux到 - 较旧的Linux交叉编译器(这将使您的二进制文件使用较旧的ABI)。