Can not load lib: virtual destructor not found (MacOS)

Hi! Recently we have faced the following problem: we have two libraries compiled in our project. Among other classes first library (libAdModel) contains a virtual class Modifiable with virtual destructor (defined, inline, empty). Some classes from the second library inherit the Modifiable. Everything is compiled by g++, processed by CINT. Both libraries can be loaded and used in ROOT/pyROOT. We were working with this structure for a while without any problems on linux.

But when we tried to run our software on MacOS, root failed to load the second library, because ‘Symbol not found: __ZTI10Modifiable’. This symbol corresponds to the ‘virtual ~Modifiable(){};’ destructor.

The main difference we’ve found between Linux and MacOS compiled libraries is the section __ZTI10Modifiable was compiled to (using nm):
on linux it is in: lib/x86_64/libAdModel.so:0000000000316ea0 V _ZTI10Modifiable
on macos it’s in: lib/x86_64/libAdModel.so: 00000000000fb480 S __ZTI10Modifiable

V - means 'The symbol is a weak object’
S - means ‘The symbol is in an uninitialized data section for small objects.’

Except this currently we’ve no other clues, what can be the reason of such behavior and how it can be fixed.
Is it a ROOT issue so ROOT can not find a symbol in the ‘S’ section? Or is it a compilation error and we could miss some compilation flag on MacOS? Or anything else?

Thanks.

Hi,

is the destructor defined inline in the header?

Cheers,
Wim

Yes, it’s inline in the header, but we also tried to define it separately in .cc file and still get the same problem.

It seems the problem is not connected to the fact, that the destructor is compiled to the ‘S’ section, because a lot of ROOT class members are compiled to ‘S’ as well, according for example to the nm libHist.so output.

And seems not to be a ROOT problem, because the error happens on dlopen:
Message: (file “lib/x86_64/libRate2IBD.so”, line -1) dlopen error: dlopen(./lib/x86_64/libRate2IBD.so, 9): Symbol not found: __ZTI10Modifiable
Referenced from: ./lib/x86_64/libRate2IBD.so
Expected in: flat namespace
in ./lib/x86_64/libRate2IBD.so

Still we do not understand why this happens on MacOS, but not on linux.

Hi,

just a guess as it should not be needed anymore on current Mac, but used to be necessary for libPyROOT.so: you could try adding -Wl,-flat_namespace to the build of the .so. (The problem there was the existence of different link namespaces w/o that flag; with one for symbols linked in at compile time, the other for symbols loaded at runtime.)

Cheers,
Wim

We have tried to use ‘-flat_namespace’ option and it didn’t solve the problem. Maybe ‘-Wl,-flat_namespace’ will help.

Still the same problem.

Hi,

still just guessing here. Are any ‘Modifiable’ objects used in libAdModel.so? Also, does it have any other virtual methods of Modifiable defined in there? And, just to try things out, if Modifiable can be instantiated, could you add a static one to libAdModel.so to see whether that brings in the definition of the dtor?

Cheers,
Wim

It seems that we have found a problem. It’s not connected to the compilation process or ROOT itself. That happened because we have moved the script load.py which was loading necessary libraries. After moving load.py the compiled load.pyc still existed (it is ignored by svn) and was found and loaded before the load.py. The AdModel library was added later, so the compiled load.pyc lacked it, that’s why it could not find the destructor.

It took some time to figure this out, because it happened on a specific laptop of a guy who didn’t update the code for a while, so we had time to forget about cleaning *.pyc files.

Sorry for the inconvenience. Thank you.