Why does this dlopen library order matter?
I have a CandData library such that (relevant) $ nm libCandData.so
:
U _ZN10CandHandle13SetCandRecordEP10CandRecord
U _ZN10CandHandle7SetLockEv
000000011610 T _ZNK10CandRecord13GetCandHeaderEv
U _ZTI10CandHandle
And the library candidate is such that $ nm libCandidate.so
:
00000001f018 T _ZN10CandHandle13SetCandRecordEP10CandRecord
00000001f270 T _ZN10CandHandle7SetLockEv
U _ZNK10CandRecord13GetCandHeaderEv
000000241500 V _ZTI10CandHandle
Thus, they have circular dependencies. I can load them by lazy loading first, in this order with everything that works:
dlopen("libCandidate.so", RTLD_LAZY | RTLD_GLOBAL);
dlopen("libCandData.so", RTLD_NOW | RTLD_GLOBAL);
But first try to load CandData first:
dlopen("libCandData.so", RTLD_LAZY | RTLD_GLOBAL);
dlopen("libCandidate.so", RTLD_NOW | RTLD_GLOBAL);
makes dlopen report:
dlopen Error: libCandData.so: undefined symbol: _ZTI10CandHandle
What I don't understand is why this order matters? In my opinion, V
means that the symbol is loosely coupled, but has a default definition, so you can see how this might not be needed for an immediate solution. But both libraries have dependencies on them U->T
.
Why does one order work but not another?
source to share
What I don't understand is why this order matters?
Order matters because while unresolved function references can be lazy resolved, data references cannot (and are _ZTI10CandHandle
not a function).
Instead of looking at the output nm
, you should look at moving (with readelf -Wr
). You will see that the type of move-in libCandidate.so
for a symbol _ZTI10CandHandle
is different from the type of move-in for a libCandData.so
symbol _ZN10CandHandle7SetLockEv
.
source to share