0

I have a plugin-like architecture in a program where the video abstraction implementations are defined in shared libraries. I also have a common static library used by all of them:

  • myProgram (executable) -> Links against libutil (static)
  • libFoo (shared lib) -> Links against libutil (static)
  • libBar (shared lib) -> Links against libutil (static)

myProgram will load dynamically (at runtime) exactly one of libFoo or libBar.

Furthermore there is a Log class in libutil which has in its public part an include to an interface class IWriter, and in its implementation an include to a concrete class derived from IWriter named StdStreamWriter.

Both myProgram and the shared libs use this Log class. The shared libs are also compiler with -fvisibility=hidden as is the current best practice (e.g. Boost did a considerable amount of work to make this work)

Now the problem: With ASAN I get an ODR error:

SUMMARY: AddressSanitizer: odr-violation: global 'vtable for StdStreamWriter' at /path/to/StdStreamWriter.cpp

I solved similar errors by decorating the class with BOOST_SYMBOL_VISIBLE like: class BOOST_SYMBOL_VISIBLE StdStreamWriter : public IWriter.

This makes the vtable of the class "exported" so the runtime can match the vtables on loading the shared library and NOT create another one which would cause the ODR violation reported.

However here it clearly does not work.

I assume the problem is, that the class header is never included in libFoo/libBar so when compiling the shared library -fvisibility=hidden is also in effect for that class causing the vtable to not be exported.

However it does not make sense to include the class header anywhere in the shared libs, as the code doesn't use that class directly (only through the Log class where the usage is hidden in the implementation)

Is it anyhow possible to make the visibility setting of a class in a static library "transitive" so that that class is also "visible" in shared libraries linking that class/static lib?

Using Clang++8 on Linux Mint 19.2.

Flamefire
  • 5,313
  • 3
  • 35
  • 70
  • Well yes but no. The problem is very related although slightly different. But as the solution is the same and especially with the change in compilers using name comparison for type-equivalence this becomes no longer relevant – Flamefire May 26 '20 at 07:40
  • Do you compile `libutil` with `-fvisibility=hidden`? Do you sanitize myProgram, libFoo and libBar? – yugr May 27 '20 at 15:05
  • Yes all compiled with hidden visibility and sanitized – Flamefire May 28 '20 at 06:44
  • I think more details are necessary (ideally full repro). I couldn't [repro](https://github.com/yugr/question-58541216). – yugr May 30 '20 at 12:52

0 Answers0