问题
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?
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.
回答1:
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.
Objects with virtual tables residing the shared library must be destroyed before unloading the shared library1.
If the library was loaded automatically by ld.so
you cannot reload it.
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.
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.
来源:https://stackoverflow.com/questions/43121500/how-to-make-a-shared-library-reload-itself-under-linux