假设我有一个程序依赖于较新的 glibc 版本,该版本在系统中无法通过软件包获得。它给出了:
version `GLIBC_2.xxx' not found
一种解决方案是使用 glibc 静态编译二进制文件。
另一种被许多人认为“不安全”的解决方案是安装更新libc.so.6
的而不是操作系统提供的。
如果包含先前的 ABI 端点,那么第二个解决方案到底有何不安全或坏主意的地方?libc.so.6
例如,如果我运行,strings /usr/lib/libc.so.6 | grep --perl-regexp "^GLIBC_"
我可以看到很多 ABI 版本,例如:
...
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
...
因此,如果我用其中libc.so.6
包含额外glibc ABI 版本的更新版本进行覆盖,它会如何破坏旧应用程序或导致系统崩溃?
或者不是……?:)
通常,为较旧的 glibc 版本编译的二进制文件将在具有较新 glibc 的系统上运行良好,因为 glibc 向后兼容并自动处理对其 应用程序二进制接口 (ABI)的更改。它通过使用符号版本控制来实现这一魔法,其中基本上每个符号都附加一个指定其 glibc 版本的标签。
如果函数调用的语义发生变化,glibc 将包括两个版本,一个用于旧语义,另一个用于新语义,因此每个函数都标有其版本。链接器会将这两个版本视为两个不同的函数。
这种复杂的机制是必需的,因为 glibc 不是一个文件,而是包含许多部分(超过 200 个共享库)。
glibc 版本的向后兼容性一直处于跟踪之中。您可以查阅 ABI 实验室报告以 了解 glibc 的 API/ABI 更改审查。该报告由abi-compliance-checker和 abi-tracker工具生成。
对于你的问题:
Glibc 兼容性并非万无一失,但我相信您必须回到在相当旧的 Linux 版本上编译的产品才能打破它。我还要说的是,当在不同于编译它们的 Linux 版本上运行时,产品可能会崩溃不仅是因为 glibc。
所以我能给出的最佳答案是:
“它不应该破坏任何东西,而且很有可能不会破坏”。
有关详细信息,请参阅:
您问题的直接答案是,如果您使用更新的(不一定受支持的)版本。您无法保证某个功能未被删除或以您的其他(较旧)应用程序能够应对这些更改的方式进行更改。事实上,如果您的新版本不提供“垫片”来支持所谓的已删除或不兼容更改的“遗留”功能,他们将无法应对您的新版本。
因此,如果您希望自己的努力取得成功,则需要检查
Changelog(s)
以下“支持的”Glibc 版本。安全地确定发生了什么变化。:)