【问题标题】:What would happen if I delete/replace the shared library after it has been explicit loaded with dlopen()?如果我在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?
【发布时间】:2021-10-21 02:24:10
【问题描述】:

如果我在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?

dlopen() 是否将整个共享库加载到内存中? 或者从长远来看,dlopen() 必须不时引用驻留在文件系统中的先前加载的库。 如果是这样,我如何强制 dlopen() 将整个 .so 加载到内存中?

标志 RTLD_NOW 是否意味着将整个库加载到内存中?

【问题讨论】:

  • 这真是一个关于mmap的问题。如果您进行“正确”安装(写入新文件,然后重命名),则 inode 仍然可以访问,直到没有其他人使用它。如果您尝试直接写入文件,您会得到ETXTBSY(请注意,手册页具有误导性)。
  • 实际上,看起来只有可执行文件才能获得ETXTBUSY;库只会导致奇怪的崩溃。

标签: linux gcc elf


【解决方案1】:

如果我在使用 dlopen() 显式加载共享库后删除/替换共享库会发生什么?

如果你删除然后写一个同名的新文件,不会有什么不好的事情发生。但如果您覆盖现有文件,您可能会看到奇怪的崩溃。

dlopen() 是否将整个共享库加载到内存中?

没有。它只是将mmaps 放入内存中。除非您在库的代码和数据上使用mlock,否则它将是来自磁盘的demand-paged

标志RTLD_NOW是否意味着将整个库加载到内存中?

一点也不。 RTLD_NOW 与您的问题完全无关,也无济于事。


那么为什么unlink+writewrite 在现有数据上存在差异?

在 UNIX 上删除(通过unlink 系统调用)一个文件实际上并没有从磁盘中删除它——数据保留在磁盘上,直到文件的所有引用都消失了。打开的文件描述符构成这样的引用,现有的mmap 也是如此。

但是如果您覆盖已经存在mmaped 的现有文件,需求分页可能会从磁盘带来内容,这可能会带来灾难性的后果。

附:正如 o11c 所指出的,覆盖 mmaped 的文件可能会失败并显示 ETXTBUSY,但这取决于操作系统和文件系统。

【讨论】:

  • 需要引用。我刚刚尝试复制/bin/sh
  • 其实这很有趣:只有可执行文件有保护;图书馆没有。
猜你喜欢
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
相关资源
最近更新 更多