如何在Linux下重新加载共享库

时间:2017-03-30 14:59:07

标签: linux shared-libraries

我正在Linux下用C ++开发一个共享库。

例如,当新的构建可用时,共享库代码是否可以重新加载自身?

我正在考虑使用 dlclose dlopen 重新加载,但前者需要一个只能由正在运行的进程访问的句柄。

知道如何从共享库代码中检索该句柄吗?对整个想法有更好的解决方案吗?

我理解热交换是危险的,但这会使开发和测试更容易。

1 个答案:

答案 0 :(得分:3)

重建共享库时,其导出的符号地址可能会更改。

因此,在重新加载共享库时,必须重新解析其用户导入的所有符号。

在卸载共享库 1 之前,必须销毁具有驻留共享库的虚拟表的对象。

如果ld.so自动加载库,则无法重新加载。

如果应用程序使用dlopen加载了共享库,则必须再次运行相同的代码才能重新加载库并重新解析符号。

还有线程本地存储可能会使事情变得复杂。

换句话说,如果没有应用程序意识到它,重新加载共享库工作就太复杂了。

1 我曾经调试了一个有趣的错误。有一个共享库,它在运行时使用dlopen加载,并在使用后卸载。在终止期间,应用程序稍后会在std::cout析构函数中崩溃。原来,共享库正在将Boost.Date_Time对象输出到std::cout。执行此操作时,库将std::cout.imbue一个新的语言环境,其中包含来自Boost.Date_Time的自定义构面对象(构面具有虚函数)。当库被卸载时,facet对象仍然由该语言环境拥有,但是它的vtable指针引用了卸载的共享库中的虚拟表,这会在破坏facet时导致崩溃。