使用"dlopen"重新加载运行时库

Runtime library reloading using `dlopen`

本文关键字:quot 加载 运行时 新加载 dlopen 使用      更新时间:2023-10-16

正在运行的基于 c++ 的进程是否可以使用dlopen重新加载基于 C++ 的动态库。

正在运行的进程轮询新版本的动态库(使用相同的 API)。 检测到此类文件后,将执行以下操作:

  1. 使用dlclose卸载旧库
  2. 较新的 dylib 将被复制并覆盖旧版本的文件。
  3. 该过程使用以下dlopen从该位置加载较新版本
  4. 根据新加载库中dlsym设置函数指针变量。

在最后阶段,我实际上获得了所需的 API,并将其放在主代码中的函数指针中以供以后使用。

但是,似乎我的程序在第三阶段后意外崩溃。dlclose部分是否有可能在进程虚拟空间中留下一些旧库的残余? 有没有更好的方法可以做到这一点?

顺便说一下,在 Windows 中使用LoadLibrary, FreeLibrary and GetProcAddress而不是dlopen, dlclose and dlsym工作得很好。

似乎我的程序在第三阶段后意外崩溃。dlclose部分是否有可能在进程虚拟空间中留下一些旧库的残余?

这是可能的。具有函数指针的对象和在卸载的库中定义的虚函数的对象将以无效指针结束。更糟糕的是,可以将新的分面附加到标准流(例如std::cout),然后卸载实现分面的共享库。后来,当在不相关的地方使用std::cout时,它会崩溃(真实故事)。因此,您必须完全控制共享库的功能。

此外,dlopen必须使用RTLD_LOCAL调用,以便其他任何内容都不能(意外地)使用正在加载的共享库的符号并阻止其卸载。如果你做这样的壮举,你必须阅读和理解man dlopen