Created attachment 33297 [details]
The attached program built on the target with the MACHINE=beaglebone gcc-4.9.1 compiler from Yocto/OpenEmbedded poky master produces this error:
beaglebone$ g++ -std=c++1y -pthread test.cc && ./a.out
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
Based on google and discovery of these references:
I've tracked this down to ext/concurrence.h requiring the presence of __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 and __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 to use _S_atomic as the default lock policy instead of _S_mutex. Defining those macros allows the program to run correctly:
beaglebone$ g++ -DWITH_HACKERY -std=c++11 -pthread test.cc && ./a.out
I believe this is related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52839 and that a better fix is to modify ext/concurrence.h to also use _S_atomic if _GLIBCXX_ATOMIC_BUILTINS is defined even when the compare-and-swap are not. Preliminary testing suggests that this solves the problem.
The discussion at 52839 suggests there's an ABI compatibility issue here; I don't really understand that (nor, honestly, care, since in this situation the compiler's going onto an embedded system where I'm not worried about old binaries). However, if there's a reason why I shouldn't propose this as a patch to OpenEmbedded please let me know.
Those macros are only meant to be defined by the compiler, never by users.
If defining them fixes the problem it implies you are not compiling with the same ABI as your libstdc++ was built with. I can't guess more than that because you haven't provided any information on your target or how it was configured.
Thanks. The compiler and libstdc++ are built using Yocto's standard recipe for the beaglebone. Obviously there's something wrong with it; what that would be is not obvious and probably isn't a gcc problem. I'll be back when I know more.
It might be obvious in the output of 'gcc -v'.
It's not obvious to me:
beaglebone$ gcc -v
Using built-in specs.
Configured with: /prj/oe/omap/build-beaglebone-master/tmp/work-shared/gcc-4.9.1-r0/gcc-4.9.1/configure --build=x86_64-linux --host=arm-poky-linux-gnueabi --target=arm-poky-linux-gnueabi --prefix=/usr --exec_prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib/gcc --datadir=/usr/share --sysconfdir=/etc --sharedstatedir=/com --localstatedir=/var --libdir=/usr/lib --includedir=/usr/include --oldincludedir=/usr/include --infodir=/usr/share/info --mandir=/usr/share/man --disable-silent-rules --disable-dependency-tracking --with-libtool-sysroot=/prj/oe/omap/build-beaglebone-master/tmp/sysroots/beaglebone --with-gnu-ld --enable-shared --enable-languages=c,c++ --enable-threads=posix --enable-multilib --enable-c99 --enable-long-long --enable-symvers=gnu --enable-libstdcxx-pch --program-prefix=arm-poky-linux-gnueabi- --without-local-prefix --enable-target-optspace --enable-lto --enable-libssp --disable-bootstrap --disable-libmudflap --with-system-zlib --with-linker-hash-style=gnu --enable-linker-build-id --with-ppl=no --with-cloog=no --enable-checking=release --enable-cheaders=c_global --with-float=hard --with-sysroot=/ --with-build-sysroot=/prj/oe/omap/build-beaglebone-master/tmp/sysroots/beaglebone --with-native-system-header-dir=/prj/oe/omap/build-beaglebone-master/tmp/sysroots/beaglebone/usr/include --with-gxx-include-dir=/usr/include/c++/4.9.1 --enable-nls
Thread model: posix
gcc version 4.9.1 (GCC)
Yocto builds libssp libstdc++-v3 libgomp libatomic separately from gcc for packaging/cross-compile/other reasons that aren't entirely clear to me, so I suspect the issue arises there.
But one difference is that I'm using -std=c++1y (and sometimes -std=c++11). Would that be enough to be an ABI change? I haven't encountered issues on x86-64.
(In reply to Peter A. Bigot from comment #4)
> But one difference is that I'm using -std=c++1y (and sometimes -std=c++11).
> Would that be enough to be an ABI change?
No, it shouldn't be (if it is then it's a bug that needs to be fixed).
I agree nothing looks suspicious in that output. If the separately-built libstdc++ uses different configuration that would be a problem, but it's not possible to tell from that output.
I built the release 4.9.1 gcc on the beaglebone and the problem does not occur. Pretty solid evidence this is a Yocto issue. I'll take it up there.
DEAR PEOPLE FROM THE FUTURE:
The problem is that OpenEmbedded used target-specific flags to build the libraries, but did not ensure that the compiler was configured to default to the corresponding architecture. Thus the compiler was defaulting to armv5t while the libraries were built for armv7-a.
Until fixed in OpenEmbedded upstream a cleaner workaround is to add -mcpu=cortex-a8 which comes closer to matching the assumptions of the libraries.