Search code examples
c++linuxgccxercesgcc3

dynamic_cast failed when hiding symbol


I have many static libraries. One is static_lib_a.a. I create a dynamic library, dynamic_lib.so to put them together.

In static_lib_a.a, it uses xerces 3.1.1 to parse xml. The following is the code snippet in static_lib_a.a

xerces::DOMElement *pElementNode = dynamic_cast<xerces::DOMElement *>(pNode);

The type of pNode is xerces::DOMNode. It is assigned to an object of xerces::DOMElement. This line of code will do downcasting.

In order to hide all symbols of static_lib_a.a in dynamic_lib.so, I use -fvisibility=hidden to build this static library. I found if I add -fvisibility=hidden, pElementNode will return a NULL pointer in runtime.

Version of gcc compiler is 3.4.4.

Does anyone have similar issues before?


Solution

  • The root of your problem is described on the gcc wiki under the section entitled "Problems with C++ exceptions". Make sure you follow the "vague linkage" link there and read the sections on virtual tables and typeinfo.

    This all applies to your case because the classes xerces::DOMNode and xerces::DOMElement contain no non-pure, non-inline virtual functions (in fact these classes are contained entirely in headers). This means that the virtual table for either class is emitted in every object file that includes its header.

    The typeinfo symbols for either class, which are required for dynamic_cast to work properly, are emitted in the same object as the virtual table i.e. in every object file that includes its header.

    When you marked your library with hidden visibility all the typeinfo symbols for xerces::DOMNode and xerces::DOMElement in objects from static_lib_a.a were marked hidden. As the wiki page points out, this ensures that the linker will then mark it as hidden in dynamic_lib.so and your dynamic_cast will fail.