This simple program crashes "Abort trap (core dumped)" when it either expected to succeed or to catch an exception. $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc5/gcc/x86_64-portbld-freebsd11.0/5.4.0/lto-wrapper Target: x86_64-portbld-freebsd11.0 Configured with: /wrkdirs/usr/ports/lang/gcc5/work/gcc-5.4.0/configure --with-build-config=bootstrap-debug --disable-nls --enable-gnu-indirect-function --libdir=/usr/local/lib/gcc5 --libexecdir=/usr/local/libexec/gcc5 --program-suffix=5 --with-as=/usr/local/bin/as --with-gmp=/usr/local --with-gxx-include-dir=/usr/local/lib/gcc5/include/c++/ --with-ld=/usr/local/bin/ld --with-pkgversion='FreeBSD Ports Collection' --with-system-zlib --with-ecj-jar=/usr/local/share/java/ecj-4.5.jar --enable-languages=c,c++,objc,fortran,java --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --infodir=/usr/local/info/gcc5 --build=x86_64-portbld-freebsd11.0 Thread model: posix gcc version 5.4.0 (FreeBSD Ports Collection) $ pkg info gcc gcc-5.4.0_2 Name : gcc Version : 5.4.0_2 Installed on : Wed Aug 9 03:18:50 2017 IDT Origin : lang/gcc Architecture : FreeBSD:11:* Prefix : /usr/local Categories : lang java Licenses : Maintainer : gerald@FreeBSD.org WWW : http://gcc.gnu.org Comment : Meta-port for the default version of the GNU Compiler Collection Annotations : repo_type : binary repository : FreeBSD Flat size : 17.0B Description : GCC, the GNU Compiler Collection, supports a number of languages. This port pulls in gcc5 (or another version-specific port) and defines symlinks called gcc, g++, and gfortran. WWW: http://gcc.gnu.org Gerald Pfeifer <gerald@FreeBSD.org> $ uname -a FreeBSD freebsd11 11.1-RELEASE FreeBSD 11.1-RELEASE #0 r321309: Fri Jul 21 02:08:28 UTC 2017 root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64 ////////////////// Code: //////////// #include <iostream> #include <locale> int main() { try { std::locale l = std::locale("en_US.UTF-8"); } catch(std::exception const &e) { std::cerr << e.what() << std::endl; } catch(...) { std::cerr << "Unknown exception " << std::endl; } }
For got to add building/running: $ g++ test.cpp $ ./a.out Abort trap (core dumped)
Might this be related to what was just discussed a few days ago (related to libsupc++ vs libcxxrt) in PR 221288?
(In reply to Artyom Beilis from comment #1) The compile/link command did not specify: -Wl,-rpath=/usr/local/lib/gcc5 and so is likely to get more of a mix of system and gcc libraries than gcc5 is designed for. (That command line option above has details that assume typical placements of files.) A from source build of lang/gcc5 reports the need for such options.
(In reply to Mark Millard from comment #3) You can use ldd on the a,out after each type of link to see the different bindings.
Can you confirm the issue doesn't affect lang/gcc6 and lang/gcc7? The default is going to change soon per bug 219275. I can reproduce in a pristine jail with nothing but gcc5 installed. gcc49, gcc48, gcc47, gcc46 are also affected. (In reply to Mark Millard from comment #3) > The compile/link command did not specify: -Wl,-rpath=... Maybe -Wl,-rpath should be added to the specfile instead of relying on ldconfig hints roulette. Not having sane defaults is a bug. (In reply to Mark Millard from comment #3) > mix of system and gcc libraries than gcc5 Tier1 and some Tier2 archs don't have system GCC anymore. It's enough to install more than one lang/gcc* to get ambiguity about libstdc++ et al.
(In reply to Jan Beich from comment #5) >(In reply to Mark Millard from comment #3) >> mix of system and gcc libraries than gcc5 > >Tier1 and some Tier2 archs don't have system GCC anymore. It's enough to install more >than one lang/gcc* to get ambiguity about libstdc++ et al. There are still system libraries that are ambiguously bound to when the system has no gcc of its own. Use of: -Wl,-rpath=/usr/local/lib/gcc<?> for the appropriate <?> prevents that. For example: libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800fbd000) vs. libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x800e06000) But there is also the lack of: libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800b72000) when -Wl,-rpath=/usr/local/lib/gcc<?> is used. This can interact badly with binding to: libthr.so.3 => /lib/libthr.so.3 (0x8011d3000) since libthr was built based on the context for: libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800b72000) and not the implicit material in libstdc++. See bugzilla 221423. For reference: g++6 -std=c++14 -Wpedantic -Wall -pthread -Wl,-rpath=/usr/local/lib/gcc6 -O2 cpp_clocks_investigation.cpp # ldd a.out 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) and the result has crash problems from the odd mix of libstdc++ supplying what would be used from libcxxrt inlibthr. (FYI: cpp_clocks_investigation.cpp is pure standard C++ code.) (I did not notice libthr using libgcc_s but if it did then it is the same sort of problem as for libstdc++ providing when the system libcxxrt would provide.) By contrast: clang++ -std=c++14 -Wpedantic -Wall -pthread cpp_clocks_investigation.cpp # ldd a.out 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) works fine and libthr has libcxxrt to bind to (and the system libgcc_s if libthr has any binding to there). Separately from the above: -Wl,-rpath=/usr/local/lib/gcc<?> also disambiguates when having multiple lang/gcc* 's installed. But this type of context is not required for there to be binding problems.
(In reply to Mark Millard from comment #6) Dumb typo. Wrong: See bugzilla 221423. Should have been: See bugzilla 221288 .
(In reply to Jan Beich from comment #5) > Can you confirm the issue doesn't affect lang/gcc6 and lang/gcc7? > The default is going to change soon per bug 219275. I'm not sure which issue(s)/aspect(s) you are after, so I pick the following to try to answer. I strongly expect that an ldd on the original context that was using std::locale(LocaleName) would show something implying a mix of system and gcc original definitions, where at run-time a specific binding ends up being made. (But no one has posted such ldd output for the failing context(s).) I expect that what is required is producing the program and libraries it is bound to such that that they avoid the mix and bind at run time to the same implementation related materials as they all were built with. I expect that such applies to all lang/gcc* examples, including gcc6 and gcc7 and the older gcc5 (and before). This hole area of bindings is a mess. Progressing from gccN to gcc <N+1> is an example were if -Wl,-rpath=/usr/local/lib/gccN was used then it looks explicitly for files from: /usr/local/lib/gccN/ and if lang/gccN is uninstalled they will not be there to be found. It takes a rebuild or other form of forced redirection to have it try looking in: /usr/local/lib/gcc<N+1>/ instead. Even if it looks and finds a binding in the new place it can try to use, the behavior need not be compatible once bound. Some types of system have a means of leaving the libraries around for binding even when the compiler and such is no long around for the version in question. Without -Wl,-rpath=/usr/local/lib/gccN involved there are other issues. But sometimes the binding that results happens to work better than does with -rpath in use (since other libraries involved were not set up for the -rpath libraries but, say, system ones). I'm not sure there is a universal, fixed answer to which binding is better for the likes of (gcc6 example): libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800fbd000) vs. libgcc_s.so.1 => /usr/local/lib/gcc6/libgcc_s.so.1 (0x800e06000) but as things are the run-time binding is controlled via use or not of the: -Wl,-rpath=/usr/local/lib/gccN Any set of libraries that is put to use in a program but that ends up being originally based overall on a mix of the two bindings (build time) is likely to end up being a problem combination when one implementation is actually bound. However, as I understand it, that option does not determine the use or not of the likes of: libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800b72000) because a bunch of those bindings can instead be found from the likes of: libstdc++.so.6 => /usr/local/lib/gcc6/libstdc++.so.6 (0x800844000) if it is involved, even without a -rpath in the link. Again a set of libraries used in a program but that mix the original contexts is likely to end up being a problem combination. (The program needs to match as well.) It appears that avoiding mixes is generally (but not universally?) required (both for libgcc_s alternative and for libcxxrt vs. implicit in libstdc++ ). In case an example makes it clearer: For my libthr example: It appears to me that a program using libstdc++ itself or in libraries would need a libthr equivalent that had also been built based on libstdc++ as libstdc++ is now constructed. Similarly for any libgcc_s use by the libthr equivalent. An alternate would be a libstdc++ that was built based on the system libgcc_s and libcxxrt and so that libstdc++ did not provide various bindings to gcc specifics that libstdc++ now does --and there would be no gcc based libgcc_s in use. As I understand g++ and libstdc++ is not designed for this sort of structure.
Here are lang/gcc7 and system clang compile/link results as viewed by ldd (all under head -r322287 in a Virtual Box virtual machine): things look good until I try my threading example. Then one combination fails (the -rpath one!). # g++7 -std=c++14 -Wpedantic -Wall -Wl,-rpath=/usr/local/lib/gcc7 -O2 locale_failure_test.cc # ldd a.out a.out: libstdc++.so.6 => /usr/local/lib/gcc7/libstdc++.so.6 (0x800824000) libm.so.5 => /lib/libm.so.5 (0x800bb8000) libgcc_s.so.1 => /usr/local/lib/gcc7/libgcc_s.so.1 (0x800de5000) libc.so.7 => /lib/libc.so.7 (0x800ffc000) # ./a.out Note: The above did not crash but had no output. # g++7 -std=c++14 -Wpedantic -Wall -O2 locale_failure_test.cc # ldd a.out a.out: libstdc++.so.6 => /usr/local/lib/gcc7/libstdc++.so.6 (0x800824000) libm.so.5 => /lib/libm.so.5 (0x800bb8000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800de5000) libc.so.7 => /lib/libc.so.7 (0x800ffb000) # ./a.out Note: The above did not crash but had no output. # clang++ -std=c++14 -Wpedantic -Wall -O2 locale_failure_test.cc # ldd a.out a.out: libc++.so.1 => /usr/lib/libc++.so.1 (0x800824000) libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x800af0000) libm.so.5 => /lib/libm.so.5 (0x800d0e000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800f3b000) libc.so.7 => /lib/libc.so.7 (0x801151000) # ./a.out Note: The above did not crash but had no output. Replacing the locale line with: std::locale l = std::locale("NOSUCH::en_US.UTF-8"); # g++7 -std=c++14 -Wpedantic -Wall -Wl,-rpath=/usr/local/lib/gcc7 -O2 locale_failure_test.cc # ./a.out locale::facet::_S_create_c_locale name not valid # g++7 -std=c++14 -Wpedantic -Wall -O2 locale_failure_test.cc # ./a.out locale::facet::_S_create_c_locale name not valid # ./a.out collate_byname<char>::collate_byname failed to construct for NOSUCH::en_US.UTF-8 So no exception was thrown in any of the examples and the code did not fail. Trying instead: # more exception_test.cc #include <exception> int main(void) { try { throw std::exception(); } catch (std::exception& e) {} return 0; } # g++7 -std=c++14 -Wpedantic -Wall -Wl,-rpath=/usr/local/lib/gcc7 -O2 exception_test.cc # ./a.out # g++7 -std=c++14 -Wpedantic -Wall -O2 exception_test.cc # ./a.out # clang++ -std=c++14 -Wpedantic -Wall -O2 exception_test.cc # ./a.out So none of them fail. But trying my standard-C++ program that uses C++ threads: # g++7 -std=c++14 -Wpedantic -Wall -pthread -Wl,-rpath=/usr/local/lib/gcc7 -O2 cpp_clocks_investigation.cpp # ldd a.out 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 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 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.
Is this still relevant?
(In reply to w.schwarzenfeld from comment #10) Well, I tried one of my old failing examples, but for more recent g++ vintages (8 and 9) in a more recent amd64 head release ( -r350364 ) and the failure did not happen . . . # g++8 -std=c++17 -Wpedantic -Wall -pthread -Wl,-rpath=/usr/local/lib/gcc8 -O2 cpp_clocks_investigation.cpp # ldd a.out a.out: libstdc++.so.6 => /usr/local/lib/gcc8/libstdc++.so.6 (0x800661000) libm.so.5 => /lib/libm.so.5 (0x8009f5000) libgcc_s.so.1 => /usr/local/lib/gcc8/libgcc_s.so.1 (0x800a27000) libthr.so.3 => /lib/libthr.so.3 (0x800c3e000) libc.so.7 => /lib/libc.so.7 (0x800c6b000) # ./a.out . . . # g++9 -std=c++17 -Wpedantic -Wall -pthread -Wl,-rpath=/usr/local/lib/gcc9 -O2 cpp_clocks_investigation.cpp # ldd a.out a.out: libstdc++.so.6 => /usr/local/lib/gcc9/libstdc++.so.6 (0x800663000) libm.so.5 => /lib/libm.so.5 (0x800a54000) libgcc_s.so.1 => /usr/local/lib/gcc9/libgcc_s.so.1 (0x800a86000) libthr.so.3 => /lib/libthr.so.3 (0x800c9d000) libc.so.7 => /lib/libc.so.7 (0x800cca000) # ./a.out . . . Both of those worked: no "Segmentation fault (core dumped)". Like earlier for g++7, locale_failure_test.cc did not fail either. I've no 11.x or 12.x context around to test. Being based only on head, this might not be enough evidence to close the submittal.
(In reply to Walter Schwarzenfeld from comment #10) > Is this still relevant? std::locale test still fails on GCC < 6. As lang/gcc (i.e., g++ symlink) abides by GCC_DEFAULT it's not an issue since bug 219275. $ pkg install gcc48 gcc5 gcc6 gcc7 gcc8 gcc9 $ g++9 -Wl,-rpath=/usr/local/lib/gcc9 test.cpp $ ./a.out $ g++8 -Wl,-rpath=/usr/local/lib/gcc8 test.cpp $ ./a.out $ g++7 -Wl,-rpath=/usr/local/lib/gcc7 test.cpp $ ./a.out $ g++6 -Wl,-rpath=/usr/local/lib/gcc6 test.cpp $ ./a.out $ g++5 -Wl,-rpath=/usr/local/lib/gcc5 test.cpp $./a.out locale::facet::_S_create_c_locale name not valid $ g++48 -Wl,-rpath=/usr/local/lib/gcc48 test.cpp $ ./a.out locale::facet::_S_create_c_locale name not valid $ g++42 test.cpp $ ./a.out locale::facet::_S_create_c_locale name not valid As for ABI mismatch between g++ and libstdc++ when -Wl,-rpath is not passed and more than one lang/gcc* is installed it doesn't seem to crash on FreeBSD 11.3 or later. $ uname -rp 11.2-RELEASE amd64 $ pkg install gcc48 gcc5 gcc6 gcc7 gcc8 gcc9 $ g++9 test.cpp $ ./a.out Abort trap $ ldd ./a.out ./a.out: libstdc++.so.6 => /usr/local/lib/gcc48/libstdc++.so.6 (0x800822000) libm.so.5 => /lib/libm.so.5 (0x800b29000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800d56000) libc.so.7 => /lib/libc.so.7 (0x800f65000)