hidden symbol '_ZNSt12__sso_stringC1EPKcm' is not defined locally

John Steele Scott toojays@toojays.net
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 mailing list