Lazy Loading - there's even a fall back |
Rod Evans Sunday August 01, 2004
In my previous posting, I described the use of lazy loading. Of course, when we initially played with an implementation of this technology, a couple of applications immediately fell over. It turns out that a fall back was necessary.
Let's say an application developer creates an application with two dependencies. The developer wishes to employ lazy loading for both dependencies.
% ldd main foo.so => ./foo.so bar.so => ./bar.so ...
The application developer has no control over the dependency
% ldd -r bar.so symbol not found: foo (./bar.so)
The only reason this library has been successfully employed by any
application is because the application, or some other shared object within
the process, has made the
dependency
Now, suppose the application
% LD_DEBUG=bindings,symbols,files main ..... 07683: 1: transferring control: ./main ..... 07683: 1: file=bar.so; lazy loading from file=./main: symbol=bar ..... 07683: 1: binding file=./main to file=./bar.so: symbol `bar'
When control is passed to bar(), the reference it makes to
its implicit dependency foo() is not going to be found,
because the shared object
07683: 1: symbol=foo; lookup in file=./main [ ELF ] 07683: 1: symbol=foo; lookup in file=./bar.so [ ELF ] 07683: 1: 07683: 1: rescanning for lazy dependencies for symbol: foo 07683: 1: 07683: 1: file=foo.so; lazy loading from file=./main: symbol=foo ..... 07683: 1: binding file=./bar.so to file=./foo.so: symbol `foo'
Of course, there can be a down-side to this fall back. If
To prevent lazy loading from being compromised, always record those dependencies you need (and nothing else).
[5] Dependencies lazily loaded | [7] Dynamic Object Versioning |