Intended usage of _GLIBCXX_HAVE_TLS / emutls symbols on OSX

Dave Gittins dave.gittins@gmail.com
Tue Jan 7 14:42:00 GMT 2020


Homebrew package maintainers suggested the change for gcc 7.5.0
originated with the gcc source. I believe they're saying that the gcc
source will now define _GLIBCXX_HAVE_TLS to 1 by default on OSX.
Please can anyone confirm if this is true / intended?

If it *is* intended I will have to dig further into why my clang build
against that std lib now seg faults.


On Thu, 19 Dec 2019 at 17:25, Dave Gittins <dave.gittins@gmail.com> wrote:
>
> I am having a problem building on OSX with clang, against the gcc
> standard library (there are project constraints behind why I am doing
> this). I am using homebrew packages for both clang and gcc. This
> pattern worked fine until a recent gcc package upgrade and I would at
> least like to understand better what has happened. I don't believe
> there's anything wrong in gcc - however, I was hoping someone could
> help me understand the *intended* situation so I can decide what to
> do...
>
> Here's my example.cpp:
> #include <mutex>
> #include <iostream>
> int main()
> {
>     std::once_flag flag;
>     std::call_once(flag, [](){ std::cout << "Foo\n"; });
>     return 0;
> }
>
> If I build and run with any of (homebrew) clang 7.1.0, gcc 7.4.0 or
> gcc 7.5.0, it builds and runs fine:
> > /usr/local/Cellar/llvm@7/7.1.0_1/bin/clang++ -std=c++17 example.cpp -o example
> > /usr/local/Cellar/gcc@7/7.4.0_2/bin/g++-7 -std=c++17 example.cpp -o example
> > /usr/local/Cellar/gcc@7/7.5.0/bin/g++-7 -std=c++17 example.cpp -o example
>
> If I build with clang, but link against the gcc 7.4.0 std lib, it also
> builds and runs fine:
> > /usr/local/Cellar/llvm@7/7.1.0_1/bin/clang++ -isystem /usr/local/Cellar/gcc@7/7.4.0_2/include/c++/7.4.0 -isystem /usr/local/Cellar/gcc@7/7.4.0_2/include/c++/7.4.0/x86_64-apple-darwin18.5.0 -isystem /usr/local/Cellar/gcc@7/7.4.0_2/include/c++/7.4.0/backward -L /usr/local/Cellar/gcc@7/7.4.0_2/lib/gcc/7 -nostdinc++ -stdlib=libstdc++ -std=c++17 example.cpp -o example
>
> In this case, the executable has the following undefined symbols which
> are provided by the runtime stdc++ library:
> > nm example | grep __once
>                  U __ZSt14__once_functor
>                  U ___once_proxy
> > nm /usr/local/Cellar/gcc\@7/7.4.0_2/lib/gcc/7/libstdc++.6.dylib | grep __once
> 0000000000139420 S __ZSt14__once_functor
> 00000000001357c0 s
> __ZZN12_GLOBAL__N_127__get_once_functor_lock_ptrEvE23__once_functor_lock_ptr
> 00000000001354b0 d
> __ZZN9__gnu_cxx18__common_pool_baseINS_6__poolELb1EE18_S_initialize_onceEvE6__once
> 00000000000bb590 T ___once_proxy
>
> However, if I now upgrade my homebrew gcc package to 7.5.0, things
> change. I see that in this new version, _GLIBCXX_HAVE_TLS is #defined
> as 1 in c++config.h (where previously it was undefined). Building with
> gcc, <mutex> is now using __once_call and we link to the emulated TLS
> versions from the standard library:
> > /usr/local/Cellar/gcc@7/7.5.0/bin/g++-7 -std=c++17 example.cpp -o example
> > nm example | grep __once
>                  U ___emutls_v._ZSt11__once_call
>                  U ___emutls_v._ZSt15__once_callable
>                  U ___once_proxy
> > nm /usr/local/Cellar/gcc\@7/7.5.0/lib/gcc/7/libstdc++.6.dylib | grep __once
> 0000000000135160 d
> __ZZN9__gnu_cxx18__common_pool_baseINS_6__poolELb1EE18_S_initialize_onceEvE6__once
> 00000000001357a0 D ___emutls_v._ZSt11__once_call
> 0000000000135780 D ___emutls_v._ZSt15__once_callable
> 00000000000b7f90 T ___once_proxy
>
>
> However, if I build with clang, I get unresolved symbols - the
> compiler emits an object file that depends on _ZSt11__once_call,
> instead of ___emutls_v._ZSt11__once_call:
> > /usr/local/Cellar/llvm@7/7.1.0_1/bin/clang++ -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/x86_64-apple-darwin18.7.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/backward -L /usr/local/Cellar/gcc@7/7.5.0/lib/gcc/7 -nostdinc++ -stdlib=libstdc++ -std=c++17 example.cpp -o example
> Undefined symbols for architecture x86_64:
>   "std::__once_call", referenced from:
>       void std::call_once<main::$_0>(std::once_flag&, main::$_0&&) in
> example-cba81f.o
>   "std::__once_callable", referenced from:
>       void std::call_once<main::$_0>(std::once_flag&, main::$_0&&) in
> example-cba81f.o
>       void std::call_once<main::$_0>(std::once_flag&,
> main::$_0&&)::'lambda0'()::operator()() const in example-cba81f.o
> ld: symbol(s) not found for architecture x86_64
> clang-7: error: linker command failed with exit code 1 (use -v to see
> invocation)
>
> I thought maybe I could fix this by adding -femulated-tls. This seems
> to cause the compiler to link to the correct symbol name in the
> standard lib, but it segfaults at runtime when calling call_once:
> > /usr/local/Cellar/llvm@7/7.1.0_1/bin/clang++ -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/x86_64-apple-darwin18.7.0 -isystem /usr/local/Cellar/gcc@7/7.5.0/include/c++/7.5.0/backward -L /usr/local/Cellar/gcc@7/7.5.0/lib/gcc/7 -nostdinc++ -stdlib=libstdc++ -std=c++17 example.cpp -o example -femulated-tls
> > ./example
> Segmentation fault: 11 (core dumped)
>
>
>
> I am unclear on the following:
> 1. Is it valid/sensible to define _GLIBCXX_HAVE_TLS for the gcc build
> on OSX? I asked this also on the homebrew forum:
> https://discourse.brew.sh/t/is-it-deliberate-that-the-gcc-7-7-5-formula-now-has-glibcxx-have-tls-defined/6500
> 2. Is there any performance or functionality reason to force the
> decision on whether this should be defined or not?
> 3. Given that it works if I build with gcc 7.5.0 against its own std
> lib, why does the clang build with -femulated-tls segfault?
>
>
> As I said above I realise this is an issue with how these compiler
> packages are being built and what I am trying to do with them, not a
> gcc problem - and it may just be unsupported. However I would be very
> appreciative of any insight on my above questions or suggestions of
> where to go from here.
>
> Dave



More information about the Gcc-help mailing list