在Linux上使用GNU Libc编译并在eglibc上运行的危险性是什么?

8

我有一个可执行文件,基本上只依赖于libc。ldd的输出如下:

libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b53156b9000)
libutil.so.1 => /lib64/libutil.so.1 (0x00002b53158d5000)
librt.so.1 => /lib64/librt.so.1 (0x00002b5315ad8000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b5315ce2000)
libm.so.6 => /lib64/libm.so.6 (0x00002b5315ee6000)
libc.so.6 => /lib64/libc.so.6 (0x00002b5316169000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a06600000)

我已经在一个旧的CentOS 6上编译了这个。运行/lib64/libc.so.6,会显示如下信息:

GNU C Library stable release version 2.5, by Roland McGrath et al.
...

这个可执行文件在其他Linux版本上运行是否安全?特别是在拥有eglibc的Ubuntu和Debian机器上运行是否安全?我编译的可执行文件似乎在12.04 LTS上运行良好,但我能相信它没有微妙的错误并且也可以在这些发行版的其他版本上运行吗?


这取决于你的可执行文件实际在做什么... - Basile Starynkevitch
@BasileStarynkevitch 怎么了? - shoosh
2个回答

5
EGLIBC旨在与GLIB兼容,这一点可以从其功能页面中了解到,因此只要使用默认配置(例如Debian版本),您就不会遇到任何问题-即不使用某些比GLIBC功能少的版本。特别是,您可以阅读Debian转换为EGLIBC的公告。请记住,如果EGLIBC不完全与GLIBC兼容,那么从Debian切换到EGLIBC是不合理的,因为它可能会破坏旧版二进制文件或来自Debian存储库之外的软件。如果您使用的是EGLIBC的精简版本,则只有在不使用从库中删除的某些功能时才不会出现问题。例如,使用GLIBC编译的二进制文件应该可以在没有套接字的EGLIBC版本上正常工作,只要它不使用它们。

2
有趣的是,EGLIBC目前正在逐渐消亡。该项目页面宣布了其最后一个版本2.19。人们(包括Debian)很快将不得不回到GLIBC。 - Earth Engine
@EarthEngine 是的,这是另一个问题。然而,根据他们所说,尽管他们不进行主动开发,但他们确实会合并对 GLIBC 所做的提交。无论如何,正如你所说,Debian 迟早需要回到 GLIBC。 - jdehesa

1

@javidcf正确,在一般情况下,eglibc和glibc是ABI兼容的,也就是说,用glibc编译的东西在eglibc上运行不应该有问题。

但是,您可能会遇到与glibc版本不一致相关的问题,而不是与glibc vs. eglibc相关的问题。某些glibc函数末尾带有版本标签(例如“printf@@GLIBC_2.2.5”,在nm上查看或通过二进制文件运行字符串并搜索GLIBC来查找)。我认为这些表示运行结果二进制文件所需的最低glibc版本要求。简单程序可能没有或只有少量此类函数,而复杂程序可能具有多个要求。以下是在Ubuntu 14.04上运行我的firefox二进制文件时运行strings的结果:

$ strings /usr/lib/firefox/firefox | grep GLIBC
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.4
GLIBC_2.3.2
GLIBC_2.3.4
GLIBC_2.17
GLIBCXX_3.4

这意味着我至少需要2.17版本的glibc库来解析运行此程序所需的符号。
其结果是,在旧版发行版上编译的二进制文件很有可能在新版上运行;但是,在新版发行版上编译的二进制文件,针对使用较高最低要求标记的较新函数的新版glibc,可能不会在旧系统上运行。例如,您的CentOS 6二进制文件可能无法在CentOS 5或Ubuntu 10.04上运行,但可能在CentOS 7和Ubuntu 12.04/14.04上正常运行。
如果您想要(更好地)获得可移植的二进制文件,则静态链接是更好的选择。

没错。但是,这是一个版本问题,当加载器加载二进制文件时会出现,对吧?我的意思是,当尝试执行程序时可能会收到错误消息(有趣的是,我昨天就遇到了这种情况),但是,为了明确起见,如果您的程序已经正确加载并开始运行(没有未解析的符号),它将与GLIBC一样运行 - 也就是说不会出现“微妙的错误”。 - jdehesa
正确。只要符号解析正确,你就不应该遇到任何问题。 - clemej

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接