How to make a shared library reload itself under Linux - linux

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.

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.

Related

How to prevent 'missing library' error linux

I am working on a cross platform, building on PC running on ARM.
I have several targets with different sets of shared libraries.
I am building a single executable which is linked with all the shared libraries.
I can't run it on targets that some shared libraries missing on. I get loader error.
Is there a way to 'tell' the loader to ignore the missing shared libs?
I will deal the the missing functions in run-time, I really need one executable..
No. You cannot tell the dynamic loader to ignore missing libraries.
What you can do is load the libraries dynamically using functions like dlopen and dlsym.

Mixing /MD and /MT in single dll

I have dll project in Visual Studio 2012, which is compiled with /MT (static multi-threaded runtime library). It also links third-party static lib, also compiled with /MT (library A), no problem so far.
The problem comes with another static lib (library B), which is unfortunatelly compiled with /MD. In my dll, i need to link both and there is no alternative to any of them (and I cannot recompile them with different option). I was able to successfully link everything together, but now I have problems with memory allocation and deletion - sometimes it fails to delete allocated object, sometimes another weird errors occurs. I believe it's caused by mixed memory managment functions, used by different parts of my dll - when new is called, object is created in library B, but when delete is called, it tries to release memory using different set of functions-, but I might be wrong.
So my question is, is this really caused by mixed memory-managment functions? And if so, is there any way to get this work together?
The only solution I think of is to wrap library B in another dll compiled with /MD and then use it from original dll to ensure different memory managment functions will be used. I'm not sure, if this would help and I would like to avoid it.
You already seem to have understood the cause of the problems you're seeing, and it is described on MSDN as follows
If it's really not possible to get all your linked libraries to use the same version of the CRT, then your only possible choice is to avoid passing CRT objects across the boundaries of these modules. Whether or not you can do this with your scenario is entireley dependent on your application. The crucial point in the above article is this sentence:
If you design your DLL so that it passes CRT objects across the boundary or allocates memory and expects it to be freed outside the DLL, you restrict the DLL users to use the same copy of the CRT library as the DLL. The DLL and its users use the same copy of the CRT library only if both are linked with the same version of the CRT DLL.
I know you've stated that it is not possible to obtain or build compatible modules to link to your application but I would recommend that you revisit this exhaustively and avoid mixing different CRT libraries at all costs.

linux dlopen can i get notification in my library when dlopen() is called in a process?

can i get the notification in my library in a process, whenever any new library is loaded from any other library in the same process with dlopen() function on linux?
Thanks.
Build a library interposer that interposes dlopen().
With dynamic linking, you can intercept any function call an application makes to any shared library. Once you intercept it, you can do whatever you want in that function, as well as call the real function the application originally intended to call.
Take a look at rtld-audit - auditing API for the dynamic linker.
http://man7.org/linux/man-pages/man7/rtld-audit.7.html
You should build a shared library with specific functions, and you should be notified with the different events. Once you have your library you will need to set LD_AUDIT to your shared library.

Crash using variables declared __declspec(thread)

I have a DLL (written in C) that uses static thread local storage (__declspec(thread)), and I want to use this DLL from a Visual Basic graphic interface.
Unfortunately, when running the interface on Windows XP that DLL which use static thread local storage crashes when it try to acess its thread variables.
How can I solve this problem?
Thanks,
Regards
G.B.
PS
I would like to not modify the DLL.
This is a known limitation of static TLS. Although you aren't explicitly calling LoadLibrary(), the VB runtime does so on your behalf.
Note that this limitation has been lifted from Vista. The most comprehensive reference that I know of is on Ken Johnson's blog.
You may be able to get around the problem if you could get the DLL included in the imports table of the generated .exe, which would likely involve some PE hacking and I'm far from certain it's a viable strategy. Otherwise you'll need to change the DLL.

Hooking windows API functions to intercept dll loading (Windows only)

I want to intercept dll's loading so I can use them. My first idea was to hook GetProcAddress. Surprisingly, by hooking it, I can only intercept calls made within the process that owns my library. (I opened another executables that call GetProcAddress and those calls don't get intercepted) (I guess because it is dynamically compiled against my lib)
Example of the output:
C:\Windows\syswow64\kernel32.dll
Module32NextW
C:\Windows\syswow64\kernel32.dll
CreateToolhelp32Snapshot
C:\Windows\system32\DINPUT.dll
DirectInputCreateW
C:\Windows\SysWOW64\ntdll.dll
DirectDrawCreate
Anyway, what I want to know is where I should start to be able to intercept dlls loading so I can then use their functions.
Basically, I want to be able to call GetModuleInformation for any dll loaded.
First, what are you doing that requires a global hook?
If you want to be notified that a DLL has loaded in any process, you can look into PsSetImageLoadNotifyRoutine, which is a kernel-mode routine.
Despite it being kernel mode, it's not very hard to use and writing a basic driver is pretty fun.
Another way would be to force a load of your library in every process. There are a variety of methods, one of the more legit ones would be Windows Message hooks.
Install a system-wide hook on the LoadLibrary function.
(I have no idea how to use that small comment thing underneath the question so)

Resources