Bug 221288 - lang/gcc5 links against libsupc++ when compiling
Summary: lang/gcc5 links against libsupc++ when compiling
Status: New
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: i386 Any
: --- Affects Only Me
Assignee: freebsd-toolchain mailing list
Depends on:
Reported: 2017-08-06 17:57 UTC by rm
Modified: 2017-08-16 03:48 UTC (History)
6 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description rm 2017-08-06 17:57:03 UTC
I get this stacktrace using a program compiled with gcc 5.4.0 from ports. It is
gcc5-5.4.0_3                   GNU Compiler Collection 5

but previous package versions of 5.4 had the same issue. I cannot try out how 6.4 fares, because it fails to compile gnustep stuff for me.

#0  0x00000000 in ?? ()
#1  0x29c0ad42 in __cxxabiv1::__dynamic_cast (src_ptr=0x2e904a80,
   src_type=0x2973c618 <typeinfo for icu::UObject>,
   dst_type=0x2973d8b8 <typeinfo for icu::UnicodeString>, src2dst=0)
   at /usr/ports/lang/gcc5/work/gcc-5.4.0/libstdc++-v3/libsupc++/dyncast.cc:72
#2  0x2942d51d in icu::Calendar::makeInstance(icu::Locale const&, UErrorCode&)
   () from /usr/local/lib/libicui18n.so.58
#3  0x2942d3ba in icu::LocaleCacheKey<icu::SharedCalendar>::createObject(void const*, UErrorCode&) const () from /usr/local/lib/libicui18n.so.58
#4  0x296d190f in icu::UnifiedCache::_get(icu::CacheKeyBase const&, icu::SharedObject const*&, void const*, UErrorCode&) const ()
  from /usr/local/lib/libicuuc.so.58
#5  0x29438906 in void icu::UnifiedCache::get<icu::SharedCalendar>(icu::CacheKey<icu::SharedCalendar> const&, void const*, icu::SharedCalendar const*&, UErrorCode&) const () from /usr/local/lib/libicui18n.so.58
#6  0x29437d78 in void icu::UnifiedCache::getByLocale<icu::SharedCalendar>(icu::Locale const&, icu::SharedCalendar const*&, UErrorCode&) ()
  from /usr/local/lib/libicui18n.so.58
#7  0x2942e90d in icu::Calendar::createInstance(icu::TimeZone*, icu::Locale const&, UErrorCode&) () from /usr/local/lib/libicui18n.so.58
#8  0x293ec0f1 in icu::SimpleDateFormat::construct(icu::DateFormat::EStyle, icu::DateFormat::EStyle, icu::Locale const&, UErrorCode&) ()
  from /usr/local/lib/libicui18n.so.58

and David Chisnall tells me:
This is quite surprising.  On FreeBSD, this function should be provided by libcxxrt, not libsupc++.  Please file a bug report with the FreeBSD gcc maintainer - it looks as if you’ve somehow ended up with a program linking both libc++ from base and libstdc++ from ports, and the libstdc++ from ports is incorrectly using its own internal libsupc++ instead of the system-provided libcxxrt (which I wrote, so can help debugging a bit better).
Comment 1 Gerald Pfeifer freebsd_committer 2017-08-07 04:42:33 UTC
GCC really is supposed to work with libstdc++, what is being put together
on FreeBSD is not tested anywhere else (and not supported by upstream from
all I know).

Still, perhaps someone on toolchain@ can lend a helping hand?
Comment 2 Mark Millard 2017-08-07 04:55:32 UTC
If I were trying to help someone with this I'd want to
see the full text for the compile and link commands,
be they from personal builds or from port builds.

That would be part of a "how to reproduce" set of

There might be ldd output that would be appropriate
as well.
Comment 3 Jan Beich freebsd_committer 2017-08-07 06:37:00 UTC
(In reply to Gerald Pfeifer from comment #1)
> GCC really is supposed to work with libstdc++,

I guess, comment 0 alludes to base r233749 trick[1]. If ported to lang/gcc* it'd make USE_GCC usage in C++ ports less dangerous on CLANG_IS_CC architectures as Clang on FreeBSD 10+ defaults to libc++. OTOH, Clang on FreeBSD has broken support for libstdc++ from ports i.e., --gcc-toolchain=/usr/local/lib/gccN is nop.

[1] https://wiki.freebsd.org/NewC++Stack#Mixing_Libraries_using_Libc.2B-.2B-_and_Libstdc.2B-.2B-
Comment 4 David Chisnall freebsd_committer 2017-08-07 07:43:35 UTC
(In reply to Gerald Pfeifer from comment #1)

Using libstdc++ is moderately dangerous on FreeBSD, as it is not the system C++ standard library.  It is only moderately dangerous though, because it uses different symbol names for the standard library symbols and so should result in a hard linker error if attempting to use it for a public interface with something linked against libc++.

Using libsupc++; however, is very dangerous.  It exports symbols with the same names as those exported by libcxxrt.  These are likely to interfere in ways that cause exciting forms of breakage.  The gcc ports should not be installing a libstdc++ that links to libsupc++.

As to clang not working with libstdc++, last time I tried it -stdlib=libstdc++ worked, and would pick up the correct libstdc++ if the correct -I and -L flags were passed.  If this doesn't work, please file a bug report.  As far as I know, --gcc-toolchain is a compile-time configuration option (from the old and now removed autoconf LLVM build system) to specify the default path for headers, not a compiler flag.
Comment 5 Mark Millard 2017-08-08 18:52:05 UTC
I suspect this mix of infrastructures ties in to
why standard c++ threading fails under the likes
of g++6 compiles while the code works when compiled
and linked via system clang++ 5. The infrastructure
issues may extend to the libgcc_s that is used as

(The program here is just one that I happen to have
around, not minimized, but standard C++ code only.)

Starting without an explicit -pthread :

g++6 -std=c++14 -Wpedantic -Wall -Wl,-rpath=/usr/local/lib/gcc6 -O2 cpp_clocks_investigation.cpp

(So no -pthread explicitly.)

Note the lack of both libthr.so.3 and libcxxrt.so.1 in
the below. Also the libgcc_s being from gcc6 materials.

# ldd a.out
	libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x800844000)
	libm.so.5 => /lib/libm.so.5 (0x800bd9000)
	libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x800e06000)
	libc.so.7 => /lib/libc.so.7 (0x80101d000)

leads to:

static inline int
__gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
                  void *__args)
  return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);

getting SIGSEGV from pthread_create not having a good address.

With -pthread the a.out produced gets a SIGSEGV in infrustrature.
Showing similar to the above information:

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

Note the libthr.so.3 but the lack of libcxxrt.so.1 in
the below.  Also the libgcc_s being from gcc6 materials.

# ldd a.out
	libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x800844000)
	libm.so.5 => /lib/libm.so.5 (0x800bd9000)
	libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x800e06000)
	libthr.so.3 => /lib/libthr.so.3 (0x80101d000)
	libc.so.7 => /lib/libc.so.7 (0x801245000)

(run in /usr/local/bin/gdb :)

Thread 11 received signal SIGSEGV, Segmentation fault.
[Switching to LWP 100288 of process 18022]
uw_frame_state_for (context=context@entry=0x7fffdfdfce20, fs=fs@entry=0x7fffdfdfcb70) at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.4.0/libgcc/unwind-dw2.c:1249
1249	      return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
(gdb) bt
#0  uw_frame_state_for (context=context@entry=0x7fffdfdfce20, fs=fs@entry=0x7fffdfdfcb70) at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.4.0/libgcc/unwind-dw2.c:1249
#1  0x0000000800e1602b in _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0x80069cc30, context=context@entry=0x7fffdfdfce20) at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.4.0/libgcc/unwind.inc:155
#2  0x0000000800e16364 in _Unwind_ForcedUnwind (exc=0x80069cc30, stop=0x801033450 <thread_unwind_stop>, stop_argument=<optimized out>)
    at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.4.0/libgcc/unwind.inc:207
#3  0x00000008010332b3 in _Unwind_ForcedUnwind (ex=<optimized out>, stop_func=0x7fffdfdfc948, stop_arg=0x80069ca00) at /usr/src/lib/libthr/thread/thr_exit.c:106
#4  thread_unwind () at /usr/src/lib/libthr/thread/thr_exit.c:172
#5  _pthread_exit_mask (status=<optimized out>, mask=<optimized out>) at /usr/src/lib/libthr/thread/thr_exit.c:254
#6  0x00000008010330db in _pthread_exit (status=0x80069ca00) at /usr/src/lib/libthr/thread/thr_exit.c:206
#7  0x0000000801025c0d in thread_start (curthread=0x80069ca00) at /usr/src/lib/libthr/thread/thr_create.c:289
#8  0x00007fffdfbfd000 in ?? ()
Backtrace stopped: Cannot access memory at address 0x7fffdfdfd000

Note #3 -> #4 goes from:


So: from system libthr to gcc6's libgcc .

System clang++ 5 with -pthread (link fails without it):

clang++ -std=c++14 -Wpedantic -Wall -pthread cpp_clocks_investigation.cpp 

# ldd a.out
	libc++.so.1 => /usr/lib/libc++.so.1 (0x8008a6000)
	libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800b72000)
	libm.so.5 => /lib/libm.so.5 (0x800d90000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800fbd000)
	libthr.so.3 => /lib/libthr.so.3 (0x8011d3000)
	libc.so.7 => /lib/libc.so.7 (0x8013fb000)

This a.out runs to completion just fine.
Comment 6 Mark Millard 2017-08-08 18:59:04 UTC
(In reply to Mark Millard from comment #5)

To avoid confusion from a typing/editing
error. . .

"Note #3 -> #4 goes from" in the reference
to the g++6 based a.out backtrace should
have been:

"Note #3 -> #2 goes from".
Comment 7 Mark Millard 2017-08-08 19:04:17 UTC
(In reply to Mark Millard from comment #5)

FYI: An older report of the threading issues
with the tiny program:

static void f() {}

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

is bugzilla 212330 .
Comment 8 Mark Millard 2017-08-08 20:29:23 UTC
(In reply to Mark Millard from comment #7)

Looking at its details bugzilla 212330 is not
a good example for here in 221288. For one the
failing context was armv6 and amd64 worked.

The failing thread call sequence is not a
match either. It was for __gthread_once
going to _pthread_once (so gthr-default.h
into the system libthr).
Comment 9 Mark Millard 2017-08-08 22:11:58 UTC
(In reply to Mark Millard from comment #6)

Returning to a g++6 based a.out back trace 
for the C++ threading to show some
infrastructure usage involved:

Thread 12 received signal SIGSEGV, Segmentation fault.
[Switching to LWP 100277 of process 18243]
uw_frame_state_for (context=context@entry=0x7fffdfbfbe20, fs=fs@entry=0x7fffdfbfbb70) at /usr/obj/portswork/usr/ports/lang/gcc6/work/gcc-6.4.0/libgcc/unwind-dw2.c:1249
1249	      return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
(gdb) disass
Dump of assembler code for function uw_frame_state_for:
. . .
   0x0000000800e14a6e <+94>:	callq  0x800e08870 <_Unwind_Find_FDE@plt>
   0x0000000800e14a73 <+99>:	test   %rax,%rax
   0x0000000800e14a76 <+102>:	mov    %rax,%r12
   0x0000000800e14a79 <+105>:	je     0x800e14bd8 <uw_frame_state_for+456>
. . .
   0x0000000800e14bd8 <+456>:	mov    0x98(%r15),%rax
=> 0x0000000800e14bdf <+463>:	cmpl   $0x247c8d48,(%rax)
   0x0000000800e14be5 <+469>:	je     0x800e14e62 <uw_frame_state_for+1106>
   0x0000000800e14beb <+475>:	nopl   0x0(%rax,%rax,1)
   0x0000000800e14bf0 <+480>:	mov    $0x5,%eax
   0x0000000800e14bf5 <+485>:	add    $0x38,%rsp
   0x0000000800e14bf9 <+489>:	pop    %rbx
   0x0000000800e14bfa <+490>:	pop    %rbp
   0x0000000800e14bfb <+491>:	pop    %r12
   0x0000000800e14bfd <+493>:	pop    %r13
   0x0000000800e14bff <+495>:	pop    %r14
   0x0000000800e14c01 <+497>:	pop    %r15
   0x0000000800e14c03 <+499>:	retq   
. . .

which matches up with the 0x247c8d48 comparison code


in the source:
. . .
#ifdef __x86_64__
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_freebsd_fallback_frame_state

static _Unwind_Reason_Code
(struct _Unwind_Context *context, _Unwind_FrameState *fs)
  struct sigframe *sf;
  long new_cfa;

  /* Prior to FreeBSD 9, the signal trampoline was located immediately
     before the ps_strings.  To support non-executable stacks on AMD64,
     the sigtramp was moved to a shared page for FreeBSD 9.  Unfortunately
     this means looking frame patterns again (sys/amd64/amd64/sigtramp.S)
     rather than using the robust and convenient KERN_PS_STRINGS trick.

     <pc + 00>:  lea     0x10(%rsp),%rdi
     <pc + 05>:  pushq   $0x0
     <pc + 17>:  mov     $0x1a1,%rax
     <pc + 14>:  syscall

     If we can't find this pattern, we're at the end of the stack.

  if (!(   *(unsigned int *)(context->ra)      == 0x247c8d48
        && *(unsigned int *)(context->ra +  4) == 0x48006a10
        && *(unsigned int *)(context->ra +  8) == 0x01a1c0c7
        && *(unsigned int *)(context->ra + 12) == 0x050f0000 ))
    return _URC_END_OF_STACK;
 . . .


(gdb) print context->ra
$2 = (void *) 0x7fffdf7fb000

(gdb) print *(unsigned*)(context->ra)
Cannot access memory at address 0x7fffdf7fb000
Comment 10 Mark Millard 2017-08-09 00:14:31 UTC
I looked up the tree from my lang/gcc6 build and find that
its libstdc++.a is linked in part via a bunch of:


files. Specifically:

libtool: link: /usr/local/x86_64-portbld-freebsd12.0/bin/ar rc .libs/libstdc++.a compatibility.o compatibility-debug_list.o compatibility-debug_list-2.o compatibility-c++0x.o compatibility-atomic-c++0
x.o compatibility-thread-c++0x.o compatibility-chrono.o compatibility-condvar.o .libs/libstdc++.lax/libsupc++convenience.a/del_op.o .libs/libstdc++.lax/libsupc++convenience.a/tinfo2.o .libs/libstdc++.
lax/libsupc++convenience.a/bad_typeid.o .libs/libstdc++.lax/libsupc++convenience.a/dyncast.o .libs/libstdc++.lax/libsupc++convenience.a/eh_throw.o .libs/libstdc++.lax/libsupc++convenience.a/guard.o .l
ibs/libstdc++.lax/libsupc++convenience.a/new_opv.o .libs/libstdc++.lax/libsupc++convenience.a/eh_tm.o .libs/libstdc++.lax/libsupc++convenience.a/vterminate.o .libs/libstdc++.lax/libsupc++convenience.a
/bad_array_new.o .libs/libstdc++.lax/libsupc++convenience.a/new_handler.o .libs/libstdc++.lax/libsupc++convenience.a/pbase_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/bad_array_length.o .li
bs/libstdc++.lax/libsupc++convenience.a/si_class_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/eh_exception.o .libs/libstdc++.lax/libsupc++convenience.a/new_opvnt.o .libs/libstdc++.lax/libsup
c++convenience.a/eh_call.o .libs/libstdc++.lax/libsupc++convenience.a/bad_alloc.o .libs/libstdc++.lax/libsupc++convenience.a/eh_aux_runtime.o .libs/libstdc++.lax/libsupc++convenience.a/bad_cast.o .lib
s/libstdc++.lax/libsupc++convenience.a/pointer_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/eh_globals.o .libs/libstdc++.lax/libsupc++convenience.a/pure.o .libs/libstdc++.lax/libsupc++conven
ience.a/fundamental_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/new_op.o .libs/libstdc++.lax/libsupc++convenience.a/del_ops.o .libs/libstdc++.lax/libsupc++convenience.a/atexit_arm.o .libs/l
ibstdc++.lax/libsupc++convenience.a/eh_arm.o .libs/libstdc++.lax/libsupc++convenience.a/guard_error.o .libs/libstdc++.lax/libsupc++convenience.a/array_type_info.o .libs/libstdc++.lax/libsupc++convenie
nce.a/vmi_class_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/atexit_thread.o .libs/libstdc++.lax/libsupc++convenience.a/eh_term_handler.o .libs/libstdc++.lax/libsupc++convenience.a/eh_unex_h
andler.o .libs/libstdc++.lax/libsupc++convenience.a/class_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/hash_bytes.o .libs/libstdc++.lax/libsupc++convenience.a/del_opv.o .libs/libstdc++.lax/l
ibsupc++convenience.a/eh_terminate.o .libs/libstdc++.lax/libsupc++convenience.a/del_opnt.o .libs/libstdc++.lax/libsupc++convenience.a/cp-demangle.o .libs/libstdc++.lax/libsupc++convenience.a/del_opvnt
.o .libs/libstdc++.lax/libsupc++convenience.a/vec.o .libs/libstdc++.lax/libsupc++convenience.a/del_opvs.o .libs/libstdc++.lax/libsupc++convenience.a/nested_exception.o .libs/libstdc++.lax/libsupc++con
venience.a/eh_alloc.o .libs/libstdc++.lax/libsupc++convenience.a/eh_ptr.o .libs/libstdc++.lax/libsupc++convenience.a/tinfo.o .libs/libstdc++.lax/libsupc++convenience.a/enum_type_info.o .libs/libstdc++
.lax/libsupc++convenience.a/eh_type.o .libs/libstdc++.lax/libsupc++convenience.a/function_type_info.o .libs/libstdc++.lax/libsupc++convenience.a/eh_personality.o .libs/libstdc++.lax/libsupc++convenien
ce.a/eh_catch.o .libs/libstdc++.lax/libsupc++convenience.a/new_opnt.o .libs/libstdc++.lax/libsupc++convenience.a/pmem_type_info.o
. . . (more from elsewhere) . . .

Similarly .libs/libstdc++.so.6.0.22 's link lists:


and has:


For example:

libtool: link:  /usr/obj/portswork/usr/ports/lang/gcc6/work/.build/./gcc/xgcc -shared-libgcc -B/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/./gcc -nostdinc++ -L/usr/obj/portswork/usr/ports/lang/
gcc6/work/.build/x86_64-portbld-freebsd12.0/libstdc++-v3/src -L/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/x86_64-portbld-freebsd12.0/libstdc++-v3/src/.libs -L/usr/obj/portswork/usr/ports/lang/
gcc6/work/.build/x86_64-portbld-freebsd12.0/libstdc++-v3/libsupc++/.libs -B/usr/local/x86_64-portbld-freebsd12.0/bin/ -B/usr/local/x86_64-portbld-freebsd12.0/lib/ -isystem /usr/local/x86_64-portbld-fr
eebsd12.0/include -isystem /usr/local/x86_64-portbld-freebsd12.0/sys-include     -fPIC -DPIC -D_GLIBCXX_SHARED -shared -nostdlib /usr/lib/crti.o /usr/obj/portswork/usr/ports/lang/gcc6/work/.build/./gc
c/crtbeginS.o  .libs/compatibility.o .libs/compatibility-debug_list.o .libs/compatibility-debug_list-2.o .libs/compatibility-c++0x.o .libs/compatibility-atomic-c++0x.o .libs/compatibility-thread-c++0x
.o .libs/compatibility-chrono.o .libs/compatibility-condvar.o  -Wl,--whole-archive ../libsupc++/.libs/libsupc++convenience.a ../src/c++98/.libs/libc++98convenience.a ../src/c++11/.libs/libc++11conveni
ence.a -Wl,--no-whole-archive  -L/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/x86_64-portbld-freebsd12.0/libstdc++-v3/libsupc++/.libs -L/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/x86_64-
portbld-freebsd12.0/libstdc++-v3/src -L/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/x86_64-portbld-freebsd12.0/libstdc++-v3/src/.libs -lm -L/usr/obj/portswork/usr/ports/lang/gcc6/work/.build/./g
cc -L/usr/local/x86_64-portbld-freebsd12.0/bin -L/usr/local/x86_64-portbld-freebsd12.0/lib -lc -lgcc_s /usr/obj/portswork/usr/ports/lang/gcc6/work/.build/./gcc/crtendS.o /usr/lib/crtn.o  -B/usr/obj/po
rtswork/usr/ports/lang/gcc6/work/.build/./gcc -B/usr/local/x86_64-portbld-freebsd12.0/bin/ -B/usr/local/x86_64-portbld-freebsd12.0/lib/ -Wl,-O1 -Wl,-z -Wl,relro -Wl,--gc-sections -Wl,--version-script=
libstdc++-symbols.ver   -Wl,-soname -Wl,libstdc++.so.6 -o .libs/libstdc++.so.6.0.22

where .libs/libsupc++convenience.a was linked via:

libtool: link: /usr/local/x86_64-portbld-freebsd12.0/bin/ar rc .libs/libsupc++convenience.a  array_type_info.o atexit_arm.o atexit_thread.o bad_alloc.o bad_array_length.o bad_array_new.o bad_cast.o bad_typeid.o class_type_info.o del_op.o del_ops.o del_opnt.o del_opv.o del_opvs.o del_opvnt.o dyncast.o eh_alloc.o eh_arm.o eh_aux_runtime.o eh_call.o eh_catch.o eh_exception.o eh_globals.o eh_personality.o eh_ptr.o eh_term_handler.o eh_terminate.o eh_tm.o eh_throw.o eh_type.o eh_unex_handler.o enum_type_info.o function_type_info.o fundamental_type_info.o guard.o guard_error.o hash_bytes.o nested_exception.o new_handler.o new_op.o new_opnt.o new_opv.o new_opvnt.o pbase_type_info.o pmem_type_info.o pointer_type_info.o pure.o si_class_type_info.o tinfo.o tinfo2.o vec.o vmi_class_type_info.o vterminate.o cp-demangle.o

It appears that for libstdc++.so use (dynamic linking) libsupc++
is at last partially bundled in libstdc++.so . This also seems to
be true of libstdc++.a for static linking, even if libsupc++.a
contains more.
Comment 11 Mark Millard 2017-08-16 03:48:33 UTC
Trying my standard-C++ program that uses C++ threads in a more
modern context (head -r322287, lang/gcc7) in an amd64 context
under a Virtual Box virtual machine (that is running on
Windows 10 Pro). . .

# g++7 -std=c++14 -Wpedantic -Wall -pthread -Wl,-rpath=/usr/local/lib/gcc7 -O2 cpp_clocks_investigation.cpp

# ldd a.out
	libstdc++.so.6 => /usr/local/lib/gcc7/libstdc++.so.6 (0x800844000)
	libm.so.5 => /lib/libm.so.5 (0x800bd8000)
	libgcc_s.so.1 => /usr/local/lib/gcc7/libgcc_s.so.1 (0x800e05000)
	libthr.so.3 => /lib/libthr.so.3 (0x80101c000)
	libc.so.7 => /lib/libc.so.7 (0x801244000)

# ./a.out
. . . (omitted) . . .
Segmentation fault (core dumped)

# g++7 -std=c++14 -Wpedantic -Wall -pthread -O2 cpp_clocks_investigation.cpp# ldd a.out
	libstdc++.so.6 => /usr/local/lib/gcc7/libstdc++.so.6 (0x800844000)
	libm.so.5 => /lib/libm.so.5 (0x800bd8000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800e05000)
	libthr.so.3 => /lib/libthr.so.3 (0x80101b000)
	libc.so.7 => /lib/libc.so.7 (0x801243000)

# ./a.out
. . . (omitted) . . .
End of clock tests.

So it worked for /lib/libgcc_s.so.1 but not for /usr/local/lib/gcc7/libgcc_s.so.1
and I must have been wrong about /lib/libcxxrt.so.1 being what mattered.

This threading example is a context where -Wl,-rpath=/usr/local/lib/gcc7
prevents correct operation because of cross library dependencies on
implementation details of the build-time context vs. the mismatched
runtime context for libthr.so.3 vs. libgcc_s.so.1 .

# clang++ -std=c++14 -Wpedantic -Wall -pthread -O2 cpp_clocks_investigation.cpp

# ldd a.out
	libc++.so.1 => /usr/lib/libc++.so.1 (0x800844000)
	libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800b10000)
	libm.so.5 => /lib/libm.so.5 (0x800d2e000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800f5b000)
	libthr.so.3 => /lib/libthr.so.3 (0x801171000)
	libc.so.7 => /lib/libc.so.7 (0x801399000)

# ./a.out
. . . (omitted) . . .
End of clock tests.

So this also worked. Again /lib/libthr.so.3 and /lib/libgcc_s.so.1
go together just fine.