During my last project I had to work with some libraries pre-loaded on systems, they didn't work as I wanted, but I couldn't change the system version. What to do? Live patch your libraries!
- LD_PRELOAD
- This is widely used by softwares that just want to run unmodified programs with unmodified libraries, but using different functions than libraries provides. As an example, ALSA does that by intercepting
open()
,read()
and friends from LibC with a new version that check if filename is some OSS device and then route these through ALSA. This method is pretty simple and the base for others: just create a new library with functions to override and put it in higher precedence in linker or export environment variable LD_PRELOAD pointing to these library before running the application (this have the highest precendence). If you still want to use the previous (overrided) function then you must usedlopen()
and load the original library and thendlsym()
to get the original symbol. - Have the functions in your application
- If you have your function in your own application, it will have higher precedence over libraries and will work just as LD_PRELOAD. Actually this is the same thing.
- When it doesn't work...
- Sometimes this just doesn't work, in my case it didn't work when I tried to override
gtk_image_set_from_file()
but use it fromg_object_set()
with a property that calls that function internally. My guess on why this doesn't work is because function call and declaration were in the same object and thus compiler may have inlined or did some other optimization. In this case you have to find an alternative solution and in my case was a even bigger hack:- Get an instance of
GtkImageClass
(useGTK_IMAGE_GET_CLASS()
) - Declare my own
gtk_image_ser_property()
which remember the old setter (((GObjectClass*)GtkImageClass)->set_property
) and call it if property was something different than the one that call our desired function. - Have the class to use our setter with
((GObjectClass*)GtkImageClass)->set_property = my_gtk_image_set_property;
- Get an instance of