Skip to content
Advertisement

dynamic_cast fails between “long distance” siblings on linux compilation

There is a class DerivedClass which inherits from both BaseClassA and BaseClassB publicly. All classes have virtual functions to make sure the virtual table is built properly.

BaseClassA and BaseClassB are located in Library1 and DerivedClass is in Library2.

One function in Library1 retrieves a DerivedClass in the form of a BaseClassA pointer and tries to dynamic_cast to BaseClassB but it fails. The same function works in different environments and compilers (visual studio for instance).

Extra information:

  • Reproduced with 4.1.2 and 4.5 gcc versions (read about the old gcc bug)
  • Derived class name is “Match” (thought it may collide with other library? python?)
  • There are tens of libraries compiling one after the other while linking between them.
  • nm -gC: Found the vtable address for Match
  • gdb (7.0.1): used to check the vtable address for the class but couldn’t understand much. (gdb version doesnt support “info vtbl”. gdb can’t show direct information about the class claiming it is a typedef)
  • readelf -s: I saw the symbol

I figured it might be one of the following problems

  1. duplicated symbol
  2. HIDDEN symbol somewhere in the libraries linked
  3. Duplicated vtables
  4. -E and RTLD_GLOBAL dlopen flag linker flag didn’t work (the linking is made using the makefile linker stage and probably not the dlopen.
  5. non-inline function manipulation (didnt work as well – but could be my mistake with understanding what exactly has to be done)

Been farming the web trying to find a solution. But what I want to know first is What Is The Problem? How can I focus on it?

(5) looks promising even though I didnt manage to use it.

Any suggestions would be greatly appreciated (a solution would be great as well 😉 )

Advertisement

Answer

Apparently #4 was the answer. The was a hidden feature that loads functions dynamically and had to be handles separately. Adding the -Wl,-E flags to the linking process and changing the loader flags did the trick.

What I want to know if there is any linuxy way of understanding this is the error.

Something like “ldd” command or others (top, nm, readelf, etc) that I tried but couldn’t see anything that pointed to this exact error.

Thanks SOF for continuous help in various subjects

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement