musl-cross-make icon indicating copy to clipboard operation
musl-cross-make copied to clipboard

undefined reference to `std::__atomic_futex_unsigned_base`

Open ldanko opened this issue 6 years ago • 13 comments

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.

ldanko avatar Nov 20 '19 00:11 ldanko

What command gave you those errors as output? Are you sure these symbols are supposed to exist?

richfelker avatar Nov 20 '19 00:11 richfelker

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.

ldanko avatar Nov 20 '19 00:11 ldanko

Can you check the config.log in the libstdc++ build dir to see if it looks like it did anything weird here?

richfelker avatar Nov 20 '19 00:11 richfelker

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

musl-cross-make/build/local/arm-linux-musleabihf/obj_gcc/arm-linux-musleabihf/libstdc++-v3/config.log

ldanko avatar Nov 20 '19 00:11 ldanko

I don't see anything wrong from config.log...

richfelker avatar Nov 20 '19 00:11 richfelker

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.

ldanko avatar Nov 20 '19 01:11 ldanko

Uhg, does it somehow not know how to do atomics on baseline arm (linux kuser_helper)?

richfelker avatar Nov 20 '19 01:11 richfelker

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.

ldanko avatar Nov 20 '19 02:11 ldanko

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 avatar Nov 20 '19 02:11 ldanko

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.

richfelker avatar Dec 18 '19 18:12 richfelker

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 avatar Jan 25 '23 09:01 Rubber1Duck

@Rubber1Duck I've never had to work on armv6.

ldanko avatar Jan 25 '23 09:01 ldanko

@Rubber1Duck I've never had to work on armv6.

thanks for your answer!

Rubber1Duck avatar Jan 25 '23 15:01 Rubber1Duck