musl-cross-make
musl-cross-make copied to clipboard
undefined reference to `std::__atomic_futex_unsigned_base`
Hi, Not sure it this is musl-cross-make bug or gcc bug, but on arm-linux-musleabihf (I think the same is for other arm builds) at least two symbols are missing from libstdc++:
undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_notify_all(unsigned int*)'
undefined reference to `std::__atomic_futex_unsigned_base::_M_futex_wait_until(unsigned int*, unsigned int, bool, std::chrono::duration<long long, std::ratio<1ll, 1ll> >, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> >)'
On x86_64 build both symbols are available:
$ nm x86_64-linux-musl/lib/libstdc++.so.6.0.25 | grep futex
00000000000bbf40 T _ZNSt28__atomic_futex_unsigned_base19_M_futex_notify_allEPj
00000000000bbe50 T _ZNSt28__atomic_futex_unsigned_base19_M_futex_wait_untilEPjjbNSt6chrono8durationIlSt5ratioILl1ELl1EEEENS2_IlS3_ILl1ELl1000000000EEEE
On arm:
$ nm arm-linux-musleabihf/lib/libstdc++.so.6.0.25 | grep futex
returns nothing.
What command gave you those errors as output? Are you sure these symbols are supposed to exist?
I was building some application based on Boost Asio.
It seems that the issue is caused by two macros _GLIBCXX_HAS_GTHREADS and _GLIBCXX_USE_C99_STDINT_TR1 (from bits/c++config.h), undefined at compile time but defined after compilation.
When building the toolchain contents of libstdc++-v3/src/c++11/futex.cc is not compiled because it's hidden behind
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
But when I try to use the toolchain both macros are defined and libstdc++-v3/include/bits/atomic_futex.h uses implementation which is not compiled.
See libstdc++-v3/include/bits/atomic_futex.h and libstdc++-v3/src/c++11/futex.cc for more details.
I'm not sure if those symbols are supposed to exists, but if not, both macros should be undefined.
Can you check the config.log in the libstdc++ build dir to see if it looks like it did anything weird here?
I don't see anything weird, but there is 12k lines of log. Both macros seems to be defined:
#define _GLIBCXX_USE_C99_STDINT_TR1 1
...
#define _GLIBCXX_HAS_GTHREADS 1
I don't see anything wrong from config.log...
Ahh, sorry. There are two lines of ifdefs in futex.cc.
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
The issue is with ATOMIC_INT_LOCK_FREE.
Uhg, does it somehow not know how to do atomics on baseline arm (linux kuser_helper)?
On Arm atomics support depends on architecture version, so for example building with -march=armv4 will set ATOMIC_INT_LOCK_FREE to 1, but building with -march=armv6 will set ATOMIC_INT_LOCK_FREE to 2.
It looks like the default is some low architecture version, so libstdc++ was build with ATOMIC_INT_LOCK_FREE. I was compiling my project with -march=armv7-a, so contents of the libstdc++-v3/include/bits/atomic_futex.h header didn't match.
Rebuilded the toolchain with settings matching my CPU
GCC_CONFIG += --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard
GCC_CONFIG += --enable-cxx-flags='-march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3-d16'
Now everything works fine.
This is a real bug in upstream GCC that we should patch. I'm not sure when I'll get to it, but here's a note to self to do it. By default GCC defines the ATOMIC_*_LOCK_FREE macros automatically based on presence of atomic insn patterns for the configured arch profile. A few archs override this correctly to indicate that libgcc necessarily provides atomic library functions if there is no insn pattern. See for example gcc/config/pa/pa-linux.h. ARM should do the same.
Rebuilded the toolchain with settings matching my CPU
GCC_CONFIG += --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard GCC_CONFIG += --enable-cxx-flags='-march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3-d16'Now everything works fine.
@ldanko do you have a working solution for armv6 also?
@Rubber1Duck I've never had to work on armv6.
@Rubber1Duck I've never had to work on armv6.
thanks for your answer!