【问题标题】:How to make a shared library reload itself under Linux如何让共享库在 Linux 下重新加载自己
【发布时间】:2017-03-30 14:59:07
【问题描述】:

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

当有新的构建可用时,共享库代码有没有办法自行重新加载?

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

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

我知道热插拔很危险,但这会使开发和测试变得更加容易。

【问题讨论】:

    标签: linux shared-libraries


    【解决方案1】:

    当您重建共享库时,其导出的符号地址可能会发生变化。

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

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

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

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

    还有可能使事情复杂化的线程本地存储。

    换句话说,在应用程序不知道的情况下重新加载共享库工作太复杂了。


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

    【讨论】:

    • 谢谢@Maxim。是的,应用程序使用 dlopen 加载库,我可以在 strace 中看到它。好点子!我还必须在每次重新加载后解析符号,这会使事情稍微复杂一些。
    • 有趣的例子 - 很好地突出了影响。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多