Finding Symbols - reducing dlsym() overhead |
Rod Evans Friday September 09, 2005
In a previous post, I'd explained how lazy loading provides a fall back mechanism. If a symbol search exhausts all presently loaded objects, any pending lazy loaded objects are processed to determine whether the required symbol can be found. This fall back is required as many dynamic objects exist that do not define all their dependencies. These objects have (probably unknowingly) become reliant on other dynamic objects making available the dependencies they need. Dynamic object developers should define what they need, and nothing else.
dlsym(3c) can also trigger a lazy load fall back.
You can observe such an event by enabling the runtime linkers
diagnostics. Here, we're looking for a symbol in
% LD_DEBUG=symbols,files,bindings main ..... 19231: symbol=elf_errmsg; dlsym() called from file=main [ RTLD_DEFAULT ] 19231: symbol=elf_errmsg; lookup in file=main [ ELF ] 19231: symbol=elf_errmsg; lookup in file=/lib/libc.so.1 [ ELF ] 19231: 19231: rescanning for lazy dependencies for symbol: elf_errmsg 19231: 19231: file=libnsl.so.1; lazy loading from file=main: symbol=elf_errmsg ...... 19231: file=libsocket.so.1; lazy loading from file=main: symbol=elf_errmsg ...... 19231: file=libelf.so.1; lazy loading from file=main: symbol=elf_errmsg ...... 19231: symbol=elf_errmsg; lookup in file=/lib/libelf.so.1 [ ELF ] 19231: binding file=main to file=/lib/libelf.so.1: symbol `elf_errmsg'
Exhaustively loading lazy dependencies to resolve a symbol isn't always what you want. This is especially true if the symbol may not exist. In Solaris 10 we added RTLD_PROBE. This flag results in the same lookup semantics as RTLD_DEFAULT, but does not fall back to an exhaustive loading of pending lazy objects. This handle can be thought of as the light weight version of RTLD_DEFAULT.
Therefore, if we wanted to test for the existence of a symbol within
the objects that were presently loaded within a process, we could use
% LD_DEBUG=symbols,files,bindings main ..... 19251: symbol=doyouexist; dlsym() called from file=main [ RTLD_PROBE ] 19251: symbol=doyouexist; lookup in file=main [ ELF ] 19251: symbol=doyouexist; lookup in file=/lib/libc.so.1 [ ELF ] ...... 19251: ld.so.1: main: fatal: doyouexist: can't find symbol
When
if ((handle = dlopen("foo.so", RTLD_LAZY)) != NULL) { fprt = dlsym(handle, "foo");
then intuitively the search for foo would be isolated to
In Solaris 9 8/03 we provided an extension to
Perhaps RTLD_PROBE and RTLD_FIRST can reduce your
[16] a source tour | [18] Init and Fini |