Home > Software design >  Undefined Symbol at Runtime
Undefined Symbol at Runtime

Time:04-18

We compile and link our code using CMake 3.18 on Ubuntu 18.04. The structure of the program is this:

There's an application with a main function, which loads a shared library at runtime, say lib_a.so. At runtime, this library loads two other libraries, lib_b.so and lib_c.so and uses symbols from them. lib_b.so uses symbols from lib_c.so as well.

lib_b.so and lib_c.so are compiled from submodules B and C of A.

On some systems the code runs fine. On some systems, however, we get undefined symbol error, which looks like this when the symbol that can't be found is demangled using c filt:

Unable to load lib_a.so : lib_b.so: undefined symbol: D::E::Get(std::initializer_list<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >)

Namespace D and class D::E are under a submodule of C. This submodule doesn't contain a CMakeLists.txt, and no shared or static library is produced from it. Its a directory, which contains source and header files only.

When we look at the defined symbols of lib_c.so using nm --defined-only lib_c.so, we see that there's this symbol:

D::E::Get(std::initializer_list<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >)

Our G version is 7.5.0, and CMake version is 3.18.0.

From this, we gather this is a CXX11 ABI issue. So, these are the things that we tried, separately:

  • Adding add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1), before defining the target, to the CMakeLists.txt that compiles and links lib_b.so.

  • Adding set (CMAKE_CXX_STANDARD 11), before defining the target, to the CMakeLists.txt that compiles and links lib_a.so. As this is the top module, we thought this would set c standard to 11 for all of its submodules.

  • Adding target_compile_features(target PUBLIC cxx_std_11), before defining the target, to the CMakeLists.txt that compiles and links lib_b.so.

None of solved the problem. Also, there's no change. lib_b.so looks for the same symbol, again.

However, when we write a Makefile that compiles the sources and links the shared libraries as told, the problem disappears.

CodePudding user response:

Turns out this was a third-party library issue.

As @Someprogrammerdude suggested, running CMake with VERBOSE=1 revealed that lib_b.so is linked with -D_GLIBCXX_USE_CXX11_ABI=0.

I changed it manually in B/CMakeFiles/B.dir/flags.cmake to -D_GLIBCXX_USE_CXX11_ABI=1. This time the previous error is gone.

This, however, gave another undefined symbol error with cxx11_abi regarding one of the third-party libraries that we use.

Updating the library to a version that's compiled with CXX11 ABI resolved the issue.

  • Related