In this post, I will attempt to explain the inner workings of how dynamic
loading of shared libraries works in Linux systems. This post is long -
for a TL;DR, please read the debugging cheat sheet.
It helped me troubleshoot a very peculiar issue. I just want to point out, that ldd -v which lists recursive dependencies, does not list the ones that are not found.
So the only true way to find out where a (missing) dependency is coming from is to use readelf -d <exe or lib> | grep 'NEEDED\|RPATH\|RUNPATH' and trace every dependency by hand.
Also keep in mind that for a given shared lib/executable its dependencies are searched according to the RPATH/RUNPATH specified by that dependency. So even if a path is in your executable RUNPATH, a library inside that runpath can still be missing, because its an indirect dependency of another library, which does not have RUNPATH (i.e it assumes that libs are put inside a globally accessible /etc/ld.so.conf location).
Hi, I am facing a issue which I will best try and describe as below.
I have 2 libraries in my environment which both exposes the same api.
libraryone : is a pc library,
librarytwo : is the library which is part of the embedded software which runs on a embedded system when HW is used, otherwise it runs on the same PC when run in simulation mode.
Problem:
When my application is executed, during initialization a PC library is expected to call API in usr/lib/i386…/libraryone, but it ends up calling API in myApp/libs/librarytwo. (in simulation mode). This is crashing the simulation.
Temporarily I changed api names in Library two (to which i have access), library one is part of standard installation of a package. With this the simulation runs and executes correctly.
Can you tell me how can I make the pc library call the api in usr/lib/i386…/libraryone and not the one in librarytwo.
Thanks for such a detailed explanation.
I have one issue, when I move my executable from one folder to another folder, I got follwoing error
./final: error while loading shared libraries: libprintMsg.so: cannot open shared object file: No such file or directory
But according to the explanation, I should not be getting this because I used ORGINAL as you can see
I am trying to compile a complete list of dependencies for the firefox (60.9) 32-bit executable. After reading this tutorial I can see that firefox must have been linked using the rpath flag:
Within the /usr/lib/firefox/bundled/lib directory there are a number of .so files that firefox needs to run, however, ldd does not report any of these dependencies:
Thank you for the good summary on shared libraries!
Just a small correction: You described Dynamic Linking. Dynamic Loading is done programatically using dlopen().
A process may use dlopen()/dlclose() to dynamically load/unload a shared library at any time, possibly using a dynamically supplied string as the filename. Use cases are plugins or speeding up process startup if the library code is not always/immediately used.
Consequently, ldd can not show dynamically loaded libraries.
I test your code using g++ on a Ubuntu 20.04 machine. And I found that I am able to run ./main directly. So, ld would also search the lib in the current path, right?
I agree with @Unhold. In that case, looks like with the new behavior (e.g. newer OS have the new ld linker which has --enabled-new-dtags enabled by default). One has to always set the LD_LIBRARY_PATH for dynamically loaded libraries or use --disable-new-dtags to search in the rpath (which IMO feels like a workaround). Do you know of another way to obtain the same old behavior without using the aforementioned approaches?