This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
- From: John Steele Scott <toojays at toojays dot net>
- To: gcc-help at gcc dot gnu dot org
- Date: Mon, 27 Nov 2017 16:18:42 +1030
- Subject: hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally
- Authentication-results: sourceware.org; auth=none
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?
Cheers,
John