Bug 212330 - lang/gcc6: armv6 g++ 6.2.0 or lang/gcc5 5.4.0 compiled ~10 line std::async using program gets SIGSEGV (but amd64 works)
Summary: lang/gcc6: armv6 g++ 6.2.0 or lang/gcc5 5.4.0 compiled ~10 line std::async us...
Status: New
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: arm Any
: --- Affects Only Me
Assignee: Andreas Tobler
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-09-02 12:17 UTC by Mark Millard
Modified: 2017-06-26 00:32 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Millard 2016-09-02 12:17:42 UTC
The following ~10 line program also shows the SIGSEGV behavior on armv6 (an rpi2) for running ./a.out after compiling via g++6. built with the system clang++ 3.8.0 does not have such problems. The program is a vast simplification of the original program that the crash was first discovered with.

# more g++6_build_crashes.cpp                                                                                        #include <future>       // future, async, launch::async

static void f() {}

int main(int, const char* [])
{
  auto a0{ std::async( std::launch::async, f ) };
  a0.get();
  return 0;
}

# /usr/local/bin/gdb a.out 
GNU gdb (GDB) 7.11.1 [GDB v7.11.1 for FreeBSD]
. . .
(gdb) run
Starting program: /root/c_tests/a.out 
[New LWP 100188 of process 2253]
 
Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to LWP 100188 of process 2253]
0x00000000 in ?? ()
(gdb) info threads
  Id   Target Id         Frame 
  1    LWP 100172 of process 2253 0x00000000 in ?? ()
* 2    LWP 100188 of process 2253 0x00000000 in ?? ()
(gdb) thread 1
[Switching to thread 1 (LWP 100172 of process 2253)]
#0  0x00000000 in ?? ()
(gdb) bt
#0  0x00000000 in ?? ()
#1  0x200b8acc in _pthread_once (once_control=<optimized out>, init_routine=<optimized out>) at /usr/src/lib/libthr/thread/thr_once.c:95
#2  0x00011b14 in __gthread_once (__once=0x20824030, __func=0x11660 <__once_proxy@plt>) at /usr/local/lib/gcc6/include/c++/armv6-portbld-freebsd11.0/bits/gthr-default.h:699
#3  0x0001440c in std::call_once<void (std::thread::*)(), std::thread*>(std::once_flag&, void (std::thread::*&&)(), std::thread*&&) (__once=..., 
    __f=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x11213>, __args#0=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x11207>) at /usr/local/lib/gcc6/include/c++/mutex:619
#4  0x00013004 in std::__future_base::_Async_state_commonV2::_M_join (this=0x2082400c) at /usr/local/lib/gcc6/include/c++/future:1644
#5  0x00012fb4 in std::__future_base::_Async_state_commonV2::_M_complete_async (this=0x2082400c) at /usr/local/lib/gcc6/include/c++/future:1642
#6  0x000128ac in std::__future_base::_State_baseV2::wait (this=0x2082400c) at /usr/local/lib/gcc6/include/c++/future:325
#7  0x00013b3c in std::__basic_future<void>::_M_get_result (this=0xbfbfed38) at /usr/local/lib/gcc6/include/c++/future:687
#8  0x00012ec4 in std::future<void>::get (this=0xbfbfed38) at /usr/local/lib/gcc6/include/c++/future:852
#9  0x00011df4 in main () at g++6_build_crashes.cpp:8
(gdb) thread 2
[Switching to thread 2 (LWP 100188 of process 2253)]
#0  0x00000000 in ?? ()
(gdb) bt
#0  0x00000000 in ?? ()
#1  0x200b8acc in _pthread_once (once_control=<optimized out>, init_routine=<optimized out>) at /usr/src/lib/libthr/thread/thr_once.c:95
#2  0x00011b14 in __gthread_once (__once=0x20824024, __func=0x11660 <__once_proxy@plt>) at /usr/local/lib/gcc6/include/c++/armv6-portbld-freebsd11.0/bits/gthr-default.h:699
#3  0x00013718 in std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), s
td::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_
State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::un
ique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (__once=..., __f=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x10fad>, 
    __args#0=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x10c41>, __args#1=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x10f95>, 
    __args#2=<unknown type in /root/c_tests/a.out, CU 0x0, DIE 0x10fa1>) at /usr/local/lib/gcc6/include/c++/mutex:619
#4  0x000129c4 in std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) (
    this=0x2082400c, __res=..., __ignore_failure=false) at /usr/local/lib/gcc6/include/c++/future:393
#5  0x00017b6c in std::__future_base::_Async_state_impl<std::_Bind_simple<void (*())()>, void>::_Async_state_impl(std::_Bind_simple<void (*())()>&&)::{lambda()#1}::operator()() const ()
    at /usr/local/lib/gcc6/include/c++/future:1664
#6  0x00019430 in std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<void (*())()>, void>::_Async_state_impl(std::_Bind_simple<void (*())()>&&)::{lambda()#1} ()>::_M_invoke<>(st
d::_Index_tuple<>) (this=0x2082500c) at /usr/local/lib/gcc6/include/c++/functional:1400
#7  0x000192f4 in std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<void (*())()>, void>::_Async_state_impl(std::_Bind_simple<void (*())()>&&)::{lambda()#1} ()>::operator()()
    (this=0x2082500c) at /usr/local/lib/gcc6/include/c++/functional:1389
#8  0x00018e68 in std::thread::_State_impl<std::_Bind_simple<std::__future_base::_Async_state_impl<std::_Bind_simple<void (*())()>, void>::_Async_state_impl(std::_Bind_simple<void (*())()>&&)::{lambda
()#1} ()> >::_M_run() (this=0x20825008) at /usr/local/lib/gcc6/include/c++/thread:196
#9  0x201ac464 in std::execute_native_thread_routine (__p=0x20825008) at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.2.0/libstdc++-v3/src/c++11/thread.cc:83
#10 0x200affd4 in thread_start (curthread=<optimized out>) at /usr/src/lib/libthr/thread/thr_create.c:289
#11 0x200afa90 in _pthread_create (thread=0xbfbfeb78, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at /usr/src/lib/libthr/thread/thr_create.c:185
#12 0xbfbfeb5c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

NOTE: kill or quit from gdb leads to gdb hanging, needing something like kill -9 to deal with gdb.

NOTE: "/usr/local/bin/gdb a.out a.out.core" causes gdb itself to SIGSEGV. I've no clue if this is an independent problem or not.

It only takes the one std::async use to have the problem. So far the above (and the earlier variants) always crash with SIGSEGV on the rpi2 when the g++6 compiler was used to build.

As for the compile commands used:

g++6 -g -v -std=c++14 -Wpedantic -Wall -O2 -pthread -Wl,-rpath=/usr/local/lib/gcc6 -mcpu=cortex-a7 g++6_build_crashes.cpp

Omitting the -mcpu=cortex-a7 still get the problem.

Using -O0 instead of -O2 still gets the problem.

But I'll note that my stable/11 -r304943 build and my ports builds (usr/ports -r421001 vintage) were/are based on using -mcpu=cortex-a7 . Also the system clang 3.8.0 was used to build g++6:

GNU C++14 (FreeBSD Ports Collection) version 6.2.0 (armv6-portbld-freebsd11.0)
      compiled by GNU C version 4.2.1 Compatible FreeBSD Clang 3.8.0 (tags/RELEASE_380/final 262564), GMP version 5.1.3, MPFR version 3.1.4-p1, MPC version 1.0.3, isl version none

# uname -apKU
FreeBSD rpi2 11.0-PRERELEASE FreeBSD 11.0-PRERELEASE #5 r304943M: Sun Aug 28 03:17:54 PDT 2016     markmi@FreeBSDx64:/usr/obj/clang/arm.armv6/usr/src/sys/RPI2-NODBG  arm armv6 1100502 1100502

# svnlite info /usr/src | grep "Re[vl][ai:]"
Relative URL: ^/stable/11
Revision: 304943
Last Changed Rev: 304943

# svnlite info /usr/ports | grep "Re[vl][ai:]"
Relative URL: ^/head
Revision: 421001
Last Changed Rev: 421001

# more /etc/make.conf 
DEFAULT_VERSIONS+=perl5=5.22
WRKDIRPREFIX=/usr/obj/portswork
WITH_DEBUG=
WITH_DEBUG_FILES=
MALLOC_PRODUCTION=
#
#system clang 3.8 (gcc6 rejects -march=armv7a):
#CFLAGS+= -march=armv7-a -mcpu=cortex-a7
#CXXFLAGS+= -march=armv7-a -mcpu=cortex-a7
#CPPFLAGS+= -march=armv7-a -mcpu=cortex-a7
#
#lang/gcc6's xgcc stage considers the above conflicting so use just:
CFLAGS+= -mcpu=cortex-a7
CXXFLAGS+= -mcpu=cortex-a7
CPPFLAGS+= -mcpu=cortex-a7

amd64 FreeBSD does not have this problem in my testing. Beyond amd64 FreeBSD not having the problem that armv6 has. . .

I have since booted Ubuntu Mate 16.04 on the rpi2 (armv6 / cortex-a7) and installed g++-6, g++-6 (Ubuntu 6.1.1-2ubuntu12~16.04) 6.1.1 20160510 since it was available. (So not 6.2: not a full vintage match to my FreeBSD g++6 contexts, unfortunately.)

The original program that failed on FreeBSD when compiled with g++6 (v6.2) on the same rpi2 executes just fine after being compiled on the Ubuntu Mate rpi2 configuration with g++-6 (v6.1).

So the armv6 SIGSEGV looks to not not be a generic g++6/libstdc++ problem for std::async use: it seems to be armv6 FreeBSD specific. (Unfortunately I've not been able to form fully matching versions for this comparison.)

I've also installed g++-6 on a ODROID-C2 (aarch64) Linux (Ubuntu 16.04.1) and built the original program that I discovered the problem with. g++-6 (Ubuntu 6.1.1-2ubuntu12~16.04) 6.1.1 20160510 was the compiler.

It executes just fine on the ODROID-C2 under Ubuntu Mate. (So far as I know FreeBSD does not support this type of context (yet) but it is the only aarch64 context I currently have access to.)
Comment 1 Gerald Pfeifer freebsd_committer 2016-09-03 09:26:43 UTC
Andreas, do you know where this may be coming from?  Is this related
to the ports, or more an issue with the src side of things, possibly?
Comment 2 Mark Millard 2016-09-03 20:20:18 UTC
I tried pkg install gcc5 and then compiling the original program with gcc5 on the rpi2 (armv6 context). It also gets SIGSEGV.

I also used gcc5 to compile the ~10 line program and ./a.out for that also gets the SIGSEGV. The compile command was:

g++5 -Wl,-rpath=/usr/local/lib/gcc5 -v -std=c++14 -Wpedantic -Wall -O2 -pthread g++6_build_crashes.cpp

Using "pkg install gcc5" means that I did not build gcc5 itself and clang was not involved in building gcc5.
Comment 3 Mark Millard 2016-09-03 21:58:13 UTC
I tried omitting -WL,-rpath=... for g++6 and the problem still occurs. The ldd's look like:

g++6 -v -std=c++14 -Wpedantic -Wall -O2 -pthread g++6_build_crashes.cpp

# ldd a.out
a.out:
        libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x20100000)
        libm.so.5 => /lib/libm.so.5 (0x20050000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x20073000)
        libthr.so.3 => /lib/libthr.so.3 (0x20081000)
        libc.so.7 => /lib/libc.so.7 (0x20300000)

vs.

g++6 -v -std=c++14 -Wpedantic -Wall -O2 -WL,-rpath=/usr/local/lib/gcc6 -pthread g++6_build_crashes.cpp

# ldd a.out
a.out:
        libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x20100000)
        libm.so.5 => /lib/libm.so.5 (0x20050000)
        libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x20073000)
        libthr.so.3 => /lib/libthr.so.3 (0x200a2000)
        libc.so.7 => /lib/libc.so.7 (0x20300000)