linux - 如果我在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?
问题描述
如果在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?
dlopen() 是否将整个共享库加载到内存中?或者从长远来看,dlopen() 必须不时引用驻留在文件系统中的先前加载的库。如果是这样,我如何强制 dlopen() 将整个 .so 加载到内存中?
标志 RTLD_NOW 是否意味着将整个库加载到内存中?
解决方案
如果我在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?
如果您删除然后写入一个具有相同名称的新文件,则不会发生任何不好的事情。但是,如果您覆盖现有文件,您可能会看到奇怪的崩溃。
dlopen() 是否将整个共享库加载到内存中?
不,它只是mmap
在记忆中。除非您使用mlock
库的代码和数据,否则它将从磁盘按需分页。
flag 是否
RTLD_NOW
意味着将整个库加载到内存中?
一点也不。RTLD_NOW
与您的问题无关,也无济于事。
unlink
那么为什么+write
与write
现有数据之间存在差异?
在 UNIX 上删除(通过unlink
系统调用)一个文件实际上并没有从磁盘中删除它——数据保留在磁盘上,直到对该文件的所有引用都消失了。一个打开的文件描述符构成了这样一个引用,现有的mmap
.
但是,如果您覆盖已经被mmap
编辑的现有文件,请求分页可能会从磁盘带来新的内容,可能会带来灾难性的后果。
PS 正如 o11c 所指出的,覆盖mmap
ed 的文件可能会失败ETXTBUSY
,尽管这取决于操作系统和文件系统。
推荐阅读
- java - 如何暂停/延迟,我的代码的特定部分
- python - Python:如何根据一系列条件语句的结果将元素输出到特定列
- mysql - 将 mysql 数据库凭据添加到环境变量会导致操作错误
- javascript - 如何更改 CSS 和 JS 中的 CSS 样式表?
- python - Keras:如何在每批训练时修改 keras 模型的输入
- odbc - 无法使用 ODBC 连接到 Azure SQL Server(该功能不熟悉生成服务器证书的证书颁发机构)
- amazon-web-services - Terraform 中的 AWS VPC CIDR 子网给出错误
- java - 如何使用 webclient 发布正文 x-www-form-urlencoded?
- python-3.x - 如何在使用 Flask 网络服务器时在 Python 进程之间建立套接字连接(用于进程间通信)
- list - 如何在不硬编码列名的情况下获取 pyspark 数据框中列的唯一值?