I am working on a program that loads user-created plugins using dlopen on CentOS. I am running into a problem with a plugin that has dependencies on shared libraries that also have dependencies:
libplugin.so -> libservices.so -> libconfig.so
Our program loads the dependencies into memory first, starting at the leaves of the dependency tree and moving up to the plugin, (error checking omitted in this example):
dlopen("/path_to_plugin/libconfig.so", RTLD_NOW | RTLD_GLOBAL)
dlopen("/path_to_plugin/libservices.so", RTLD_NOW | RTLD_GLOBAL)
dlopen("/path_to_plugin/libplugin.so", RTLD_NOW | RTLD_GLOBAL)
We use this approach so the end user does not have to modify their LD_LIBRARY_PATH to point to the directory with the plugins. This approach has worked successfully for several different plugins.
We recently received a new plugin for which this approach does not work. We are able to load libconfig.so successfully, but when we try to load libservices.so, we get the following error message:
Exception libconfig.so: cannot open shared object file: No such file or directory
I know that the symbol dependencies between libraries are all satisfied, because when I set LD_LIBRARY_PATH to contain the plugin path, the plugin loads and executes correctly.
When I run strace on my program, I can see that the system is performing a search for libconfig.so as described in the dlopen man page. So it appears that, for some reason, dlopen is not detecting that libconfig.so has already been loaded. What conditions could cause this behavior?