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

what will happen if you overwrite a share library (currently mapped by a program) with a new version?

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

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

可执行文件和共享库是否具有与数据文件相同的文件概念 "caching"?

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

我在 Unix 平台上工作,假设新版本共享库中的函数签名保持不变,但它们的实现发生了变化。

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

如果您尝试覆盖现有文件,您会发现这是不可能的。如果您尝试打开当前映射到可执行页面的文件进行写入,您将得到 ETXTBSY ("Text file busy")。 (这包括可执行文件和共享库。)这种保护由内核实现。

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