【问题标题】:Linux shared library version matchLinux 共享库版本匹配
【发布时间】:2018-10-07 03:11:32
【问题描述】:

我有两台机器,一台是 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 上运行?

【问题讨论】:

  • 简单:hello 程序使用 glibc-2.17 中可用的对象。 IE。没有使用对象 GLIBC_2.23。 ...mongodb(在 Ubuntu 中编译)使用仅在 glibc-2.23 中可用的对象。
  • 感谢@KnudLarsen:看我的问题2,不同构建方式的相同代码可以很好地与libc-2.17配合使用。
  • 当您使用 -lm 在 Ubuntu 中构建 mongodb 时,您将需要一个为 libm 提供 Ubuntu libc 版本 = 2.23 的 libc。规则“1”:在比目标更旧的操作系统上编译。

标签: linux linker shared-libraries glibc


【解决方案1】:

在运行二进制文件时,库加载器如何确定它找到的库(在本例中为 libc)是否可以使用?

它会查找应用程序所需的符号版本。如果所有需要的符号都可用,那么库就可以使用了。

您可以通过运行readelf -V a.out 查看需要哪些符号。

为什么我的构建无法使用 libc-2.17 运行

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2014-02-22
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多