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

1 answer

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




All Articles