hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
John Steele Scott
Mon Nov 27 05:49:00 GMT 2017
I have a project we are currently building on Centos 7 with the devtoolset-4 build of GCC 5. I'm trying to upgrade it to use GCC 7 from devtoolset-7.
The build generates a silly number of shared libraries in a fairly deep dependency tree. Some of the libraries are failing to link with:
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld.gold: error: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
Not hugely informative. I hacked gold to print the object where that symbol comes from (it's in a handful of shared objects . . . this project is shared objects all the way down), but it looks like actually this symbol is *not* defined locally:
Num: Value Size Type Bind Vis Ndx Name
664: 0000000000027b10 15 FUNC GLOBAL DEFAULT 12 _ZNSt12__sso_stringC1EPKcm
Ultimately this symbol is defined in the libstdc++_nonshared.a library that is used to provide the newer C++ symbols that are not in the base Centos' GCC 4.8.
Interestingly, in devtoolset-4 this symbol *was* hidden:
jscott@jscott-centos7:/tmp$ readelf --wide --syms /opt/rh/devtoolset-4/root/usr/lib/gcc/x86_64-redhat-linux/5.2.1/libstdc++_nonshared.a | grep _ZNSt12__sso_stringC1EPKcm | grep -v UND
117: 0000000000000000 15 FUNC GLOBAL HIDDEN 62 _ZNSt12__sso_stringC1EPKcm
Now it is not:
jscott@jscott-centos7:/tmp$ readelf --wide --syms /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++_nonshared.a | grep _ZNSt12__sso_stringC1EPKcm | grep -v UND
35: 0000000000000000 15 FUNC GLOBAL DEFAULT 11 _ZNSt12__sso_stringC1EPKcm
Since devtoolset-7 sets _GLIBCXX_USE_DUAL_ABI=0, my read of stdexcept is that std::__sso_string should just be a typedef to std::string. So what's pulling the SSO string? Other references to it in libstdc++_nonshared.a are from cow-stdexcept.o and system_error48.o. The former looks likely to be why we would be getting it - presumably many of the STL functions which throw exceptions will cause that to be required. Working around this by avoiding such calls (e.g. use bitset[n]=x instead of bitset.set(x)) is not really sustainable.
So far my attempts to recreate this in a small example (only a couple of shared libraries) haven't worked.
In a couple of instances I was able to get rid of the errors by replacing a devtoolset-4-built library with one built with the native GCC 4.8. But that doesn't seem to be globally applicable.
Any ideas on what is going on here?
More information about the Gcc-help