假设我有一个程序依赖于较新的 glibc 版本,但无法通过软件包在系统中使用。它给出:
version `GLIBC_2.xxx' not found
一种解决方案是使用 glibc 静态编译二进制文件。
另一个被许多人认为“不安全”的解决方案是使用较新的版本libc.so.6
代替操作系统自带的版本。
如何确切地libc.so.6
如果包括先前的 ABI 端点,那么第二种解决方案并不安全或者不是一个坏主意?
例如,如果我运行,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 版本如何破坏旧应用程序或导致系统崩溃?
或者不是这样...?:)
答案1
一般来说,为旧版 glibc 编译的二进制文件可以在新版 glibc 的系统上正常运行,因为 glibc 是向后兼容的,并且会自动处理其更改 应用程序二进制接口 (ABI)。它通过使用符号版本控制来实现这一魔法,基本上每个符号都附加一个指定其 glibc 版本的标签。
如果函数调用的语义发生变化,glibc 将包含两个版本,一个用于旧语义,另一个用于新语义,因此每个函数都标有其版本。链接器会将两个版本视为两个不同的函数。
这种复杂的机制是必需的,因为 glibc 不是一个文件,而是由许多部分组成(超过 200 个共享库)。
glibc 版本的向后兼容性正在不断跟踪中。您可以查阅 ABI 实验室报告 glibc 的 API/ABI 变更审查. 该报告由abi 合规性检查器和 abi-跟踪器工具。
对于您的问题:
因此,如果我使用包含附加 glibc ABI 版本的较新的 libc.so.6 进行覆盖,它会如何破坏较旧的应用程序或导致系统崩溃?还是不会......?
Glibc 兼容性并非万无一失,但我相信您必须回溯到在相当旧的 Linux 版本上编译的产品才能打破它。我还想说,当产品在不同于编译版本的 Linux 上运行时,它们可能不仅仅因为 glibc 而中断。
所以我能给出的最佳答案是:
“不是应该去破坏任何东西,而且很有可能不会发生这种事”。
有关详细信息,请参阅:For more information, see:
答案2
这直接的你的问题的答案是,如果你使用更新(不一定支持)版本。你无法保证某个函数没有已删除, 或者已更改这样,你的其他(较旧的)应用程序将能够应付有了这些变化。事实上他们惯于能够应对你的新版本,如果你的新版本没有提供“垫片”来支持所谓的“遗留”功能已删除, 或者不相容地 已更改。
因此,如果您希望成功,则需要检查Changelog(s)
以下“支持的” Glibc 版本。为了安全地确定已更改。 :)