Bug 62100

Summary: c++11 threads invoke pure virtual function on arm embedded system
Product: gcc Reporter: Peter A. Bigot <pab>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P3    
Version: 4.9.1   
Target Milestone: ---   
Host: Target: arm-linux-gnueabi
Build: Known to work:
Known to fail: Last reconfirmed: 2014-08-12 00:00:00
Attachments: reproducing code

Description Peter A. Bigot 2014-08-11 23:23:47 UTC
Created attachment 33297 [details]
reproducing code

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[16]$ g++ -std=c++1y -pthread test.cc && ./a.out
starting
joining
pure virtual method called
terminate called without an active exception
Aborted (core dumped)

Based on google and discovery of these references:

* https://groups.google.com/d/msg/automatak-dnp3/Jisp_zGhd5I/ck_Cj6nO8joJ

* http://stackoverflow.com/questions/23583317/c-11-threads-error-pure-virtual-function-called

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[17]$ g++ -DWITH_HACKERY -std=c++11 -pthread test.cc && ./a.out
starting
joining
doit
done

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.
Comment 1 Jonathan Wakely 2014-08-12 10:05:27 UTC
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.

https://gcc.gnu.org/bugs/
Comment 2 Peter A. Bigot 2014-08-12 11:27:21 UTC
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.
Comment 3 Jonathan Wakely 2014-08-12 11:50:38 UTC
It might be obvious in the output of 'gcc -v'.
Comment 4 Peter A. Bigot 2014-08-12 12:34:08 UTC
It's not obvious to me:

beaglebone[98]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/gcc/arm-poky-linux-gnueabi/4.9.1/lto-wrapper
Target: arm-poky-linux-gnueabi
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.
Comment 5 Jonathan Wakely 2014-08-12 14:46:24 UTC
(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.
Comment 6 Peter A. Bigot 2014-08-13 20:42:44 UTC
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.
Comment 7 Peter A. Bigot 2014-08-14 14:03:17 UTC
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.

See http://www.mail-archive.com/openembedded-core@lists.openembedded.org/msg55490.html