如何在Linux下重新加载共享库 [英] How to make a shared library reload itself under Linux

查看:59
本文介绍了如何在Linux下重新加载共享库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Linux下用C ++开发共享库.

I'm developing a shared library in C++ under Linux.

例如,当有新版本可用时,共享库代码中是否有办法重新加载自身?

Is there a way from the shared library code to reload itself when a new build is available for example?

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

I was thinking of using dlclose and dlopen to reload but the former needs a handle which is accessible to the running process only.

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

Any idea how to retrieve that handle from the shared library code? Any better solution to the whole idea?

我知道热插拔是危险的,但这会使开发和测试更加容易.

I understand hot swapping is dangerous but this will make development and testing much more easier.

推荐答案

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

When you rebuild a shared library its exported symbol addresses may change.

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

Hence, when reloading a shared library, all symbols its users import must be re-resolved.

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

Objects with virtual tables residing the shared library must be destroyed before unloading the shared library1.

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

If the library was loaded automatically by ld.so you cannot reload it.

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

If the application loaded the shared library using dlopen, the same code must be run again to re-load the library and re-resolve the symbols.

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

There is also thread-local storage that may complicate things.

换句话说,它太复杂而无法在应用程序不知道的情况下重新加载共享库.

In other words, it is too complicated to make re-loading a shared library work without the application being aware of it.

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

1I once debugged an intersting bug in the past. There was a shared library which was loaded at run-time using dlopen and unloaded after use. The application would later crash in std::cout destructor during termination. Turned out that the shared library was outputting Boost.Date_Time objects into std::cout. When doing so, the library would std::cout.imbue a new locale with a custom facet object from Boost.Date_Time (facets have virtual functions). When the library got unloaded, the facet object was still there owned by that locale, but its vtable pointer was referring the virtual table in the unloaded shared library, which would cause the crash when destroying the facet.

这篇关于如何在Linux下重新加载共享库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆