unix - 出于共享的目的,何时将共享库视为 "the same"?

标签 unix posix shared-libraries

我在想……当我启动一个使用共享库 A 的程序 X 时,在该程序运行时,我修改了磁盘上的共享库,并运行了另一个依赖于同一个共享库的程序 Y。该程序 Y 将使用共享库的内存中已经存在的版本,还是会加载共享库的一个不同实例并进行后续修改?

如何确定是否共享已加载的库或从磁盘重新加载它?

最佳答案

动态加载器只是做常规的旧 open(2)mmap(2)调用,并且内存映射会以与打开的 fd 相同的方式碰撞 inode 引用计数。因此,如果您对库执行通常的原子文件替换技巧,请在文件的新副本中写出您的更改,然后 rename(2)它覆盖旧名称,在该点之后启动的任何内容都将获取新 inode 和新内容,但运行程序将继续使用旧 inode 和旧内容。

如果在适当的位置修改库,自然会在write 之后启动任何程序。电话将接听您的更改。更有趣的问题是已经映射了它的进程会发生什么。答案可能是“系统不会让你这样做”或“未指定,取决于页面缓存实现的细节”。随便看看 Linux 实现(这是我必须掌握的):glibc 动态加载器使用 MAP_DENYWRITE对于它所有的共享库映射,它没有记录,但听起来像是“在映射存在时使这个文件不可修改”。但是,我在内核源代码中找不到任何内容 MAP_DENYWRITE做任何事情;它可能是历史遗迹或类似的东西。

它还使用 MAP_PRIVATE . http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html说“未指定在建立 MAP_PRIVATE 映射之后对底层对象所做的修改是否通过 MAP_PRIVATE 映射可见。”因此,您可能会也可能无法修改正在运行的进程下的共享库镜像,具体取决于页面缓存实现的详细信息。

关于unix - 出于共享的目的,何时将共享库视为 "the same"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7181921/

相关文章:

c - fork() 如何以及为什么会失败?

unix - "x$VARIABLE"中 x 的 shell 脚本用途

linux - 解压单文件挂起

c - 很好的 C 库集合?

c++ - 在跨 dll/so 的注入(inject)类中使用异常是否安全?

java - 如何正确地将共享库加载到 Eclipse 中

c++ - 如何以编程方式查找加载的共享库的版本?

unix - 重新编译二进制文件时出现总线错误

linux - 在 bash 脚本中重用虚拟文件

C posix套接字,无法将数据从客户端发送到服务器