如果用新版本覆盖共享库(当前由程序映射)会发生什么?

tec*_*e11 4 c c++ shared-libraries ld

我想知道是否有人可以解释如果您通过将新的 *.so 复制到旧的 *.so 来用新版本覆盖共享库文件(当前由程序映射)会发生什么?

显然,它不应该影响链接到旧版本的现有正在运行的程序(prog1)。但是如果您启动另一个使用相同共享库的程序(prog2)怎么办?prog2 是否会简单地映射正在运行的 prog1 当前使用的旧版本库,或者 prog2 将加载和链接新版本的共享库?

可执行文件和共享库是否像数据文件一样具有相同的文件“缓存”概念?

ld.so 是否检测共享库的版本

我正在 Unix 平台上工作,并假设新版本的共享库中的函数签名保持不变,但它们的实现已经改变。

小智 5

如果您取消原始文件的链接并将其替换为另一个文件(这是正常cpmv将要做的事情),则不会发生特别令人惊讶的情况。任何已在运行的进程将继续使用已删除的库,并且任何新启动的进程将使用新的库。

如果您尝试覆盖现有文件,您会发现这是不可能的。ETXTBSY如果您尝试打开当前映射到可执行页面的文件进行写入,您将收到一条消息(“文本文件忙”)。(这包括可执行文件和共享库。)这种保护是由内核实现的。

如果您以某种方式设法绕过这些保护并覆盖正在使用的可执行文件或共享库,则会发生不好的事情。该对象中当前换出的任何页面在调入时都将被新可执行文件的页面替换,从而导致意外行为 - 可能会崩溃。

  • 谢谢。我刚刚做了一个测试。复制成功,但之后运行的程序因核心转储而崩溃。 (2认同)