【问题标题】:Dangers of compiling with GNU Libc and running on eglibc in Linux?在 Linux 中使用 GNU Libc 编译并在 eglibc 上运行的危险?
【发布时间】:2014-05-04 16:58:45
【问题描述】:

我有一个几乎只依赖于 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 上运行良好,但我可以相信它没有细微的错误并且也可以在这些发行版的其他版本上运行吗?

【问题讨论】:

  • 这取决于你的可执行文件实际上在做什么......
  • @BasileStarynkevitch 怎么样?

标签: linux ubuntu libc eglibc


【解决方案1】:

EGLIBC 被设计为与 GLIB 兼容的 API 和 ABI,正如您可能在其features page 中看到的那样,因此只要您使用它的默认配置(如 Debian 版本)就应该没有任何问题 -即,您没有使用一些功能比 GLIBC 少的受限版本。

特别是,您可以阅读announcement of Debian switching to EGLIBC。请记住,如果 Debian 与 GLIBC 的 ABI 不完全兼容,那么从 Debian 切换到 EGLIBC 是不合理的,因为它可能破坏了遗留二进制文件或只是软件不是来自 Debian 存储库。

如果您使用的是 EGLIBC 的受限版本,除非您使用从库中删除的某些功能,否则应该没有问题。例如,使用 GLIBC 编译的二进制文件应该可以在没有套接字的 EGLIBC 版本上正常工作,只要它不使用它们。

【讨论】:

  • 一个有趣的事情是 EGLIBC 目前正在死去。该项目页面宣布了其最新版本 2.19。人们(包括 debian)很快将不得不搬回 GLIBC。
  • @EarthEngine 是的,这是另一个问题。然而,根据他们的说法,虽然他们没有进行积极的开发,但他们确实不断合并提交到 GLIBC。无论如何,正如你所说,Debian 迟早可能需要回到 GLIBC。
【解决方案2】:

@javidcf 是正确的,因为 eglibc 和 glibc 是 ABI 兼容的,因为从一般意义上来说,在 eglibc 上运行使用 glibc 编译的东西不应该有问题。

但是,您可能会遇到与 glibc 与 eglibc 无关的问题,而是与 glibc 版本偏差有关的问题。某些 glibc 函数在它们的末尾标有版本(例如“printf@@GLIBC_2.2.5”,当通过 nm 查看时,或通过在二进制文件上运行字符串并为 GLIBC 进行 grepping 时)。我相信这些代表了运行生成的二进制文件的最低 glibc 版本要求。简单的程序可能很少(或没有)这些类型的函数。复杂的程序可能有多个要求。这是我在 Ubuntu 14.04 上的 firefox 二进制文件上运行字符串的结果:

$ 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 完全一样运行 - 即不会有 “微妙的错误”
  • 正确。只要符号可以解决,您就不应该有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 2015-06-02
相关资源
最近更新 更多