I'm using g++ 11.2.0 on Ubuntu 21.10 (Pop!_OS 21.10) and trying to compile a project that uses the std::[j]thread::detach() function a lot. When I statically link it, I always get a segmentation fault for what seems to be something in the libpthread library. This happens with both std::thread and std::jthread. ldd --version shows a glibc version of 2.34 (specifically 2.34-0ubuntu3.2), and ld --version shows 2.37, both versions at which this bug should have been fixed. Here's the output of g++ -v: Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu [I'm using AMD Zen 3] Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.2.0-7ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.2.0 (Ubuntu 11.2.0-7ubuntu2) I'm compiling with the CMake command > cmake source -DADD_FLAGS="-static -lpthread" which adds these flags to the end of CMAKE_CXX_FLAGS, and > cmake --build . -j 12 to build. I can't provide the .i files because even compressed as a .tar.gz, the archive is too big (4.5MB). However, this is reproducible by cloning the repo (https://github.com/Slackadays/Hajime), cd hajime, and issuing the two CMake commands above. Output of GDB: Thread 2 "hajime" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff7ff8640 (LWP 52019)] 0x0000000000000000 in ?? () (gdb) bt #0 0x0000000000000000 in ?? () #1 0x0000000000510745 in std::thread::detach() () #2 0x000000000044ca76 in Server::startProgram (this=0x7022b0, method=...) at /home/jackson/hajime/source/server.cpp:290 #3 0x000000000044ad15 in Server::startServer (this=0x7022b0, confFile=...) at /home/jackson/hajime/source/server.cpp:112 #4 0x0000000000449d8f in std::__invoke_impl<void, void (Server::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::shared_ptr<Server>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__f= @0x6ff0c8: (void (Server::*)(Server * const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)) 0x44a298 <Server::startServer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, __t=...) at /usr/include/c++/11/bits/invoke.h:74 #5 0x0000000000449c45 in std::__invoke<void (Server::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::shared_ptr<Server>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__fn= @0x6ff0c8: (void (Server::*)(Server * const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)) 0x44a298 <Server::startServer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>) at /usr/include/c++/11/bits/invoke.h:96 #6 0x0000000000449b35 in std::thread::_Invoker<std::tuple<void (Server::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::shared_ptr<Server>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_invoke<0ul, 1ul, 2ul> (this=0x6ff098) at /usr/include/c++/11/bits/std_thread.h:253 #7 0x000000000044958a in std::thread::_Invoker<std::tuple<void (Server::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::shared_ptr<Server>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator() (this=0x6ff098) at /usr/include/c++/11/bits/std_thread.h:260 #8 0x0000000000449422 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (Server::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >), std::shared_ptr<Server>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_run ( this=0x6ff090) at /usr/include/c++/11/bits/std_thread.h:211 #9 0x00000000005104b4 in execute_native_thread_routine () #10 0x000000000058a877 in start_thread () #11 0x000000000060d814 in clone () (gdb)
Note that my CMake command includes -lpthread even though CMake has been configured to link it already with -pthread, so when reproducing it, remove -lpthread to better replicate the situation (I only realized this after posting).
This is the usual problem with weak symbols and static linking. For distros other than Red Hat (and Fedora, CentOS etc.) you need to use: -Wl,--whole-archive -lpthread -Wl,--no-whole-archive Otherwise the pthread symbols do not get pulled in by the linker. For GCC 12 and Glibc 2.34 that isn't needed, since r12-5108
See PR 52590 *** This bug has been marked as a duplicate of bug 52590 ***
(In reply to Jonathan Wakely from comment #2) > For distros other than Red Hat (and Fedora, CentOS etc.) you need to use: > > -Wl,--whole-archive -lpthread -Wl,--no-whole-archive > > Otherwise the pthread symbols do not get pulled in by the linker. This would seem like a fix, but applying those flags to both the ADD_FLAGS variable and both manually specifying then in CMakeLists.txt made no difference (I tried variations for hours but no dice).
Just for reference, another person in bug 52590 had tried the same before but also had no luck.
(In reply to Jackson Huff from comment #5) > Just for reference, another person in bug 52590 had tried the same before > but also had no luck. No, they tried a different command, not the one I suggested. I just checked out the code in an Ubuntu container and running make VERBOSE=1 I see that the flags are added to the start of the command: [100%] Linking CXX executable hajime /usr/bin/cmake -E cmake_link_script CMakeFiles/hajime.dir/link.txt --verbose=1 /usr/bin/c++ -static -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -O3 -DNDEBUG -s -flto -fno-fat-lto-objects -flto=auto CMakeFiles/hajime.dir/hajime.cpp.o CMakeFiles/hajime.dir/server.cpp.o CMakeFiles/hajime.dir/server_features.cpp.o CMakeFiles/hajime.dir/server_performance.cpp.o CMakeFiles/hajime.dir/server_performance_counters.cpp.o CMakeFiles/hajime.dir/getvarsfromfile.cpp.o CMakeFiles/hajime.dir/output.cpp.o CMakeFiles/hajime.dir/installer.cpp.o CMakeFiles/hajime.dir/deduce.cpp.o CMakeFiles/hajime.dir/languages.cpp.o CMakeFiles/hajime.dir/wizard.cpp.o CMakeFiles/hajime.dir/constants.cpp.o -o hajime That is wrong: https://web.archive.org/web/20210609020437/c-faq.com/lib/libsearch.html
Ah, but it still won't help for glibc 2.34 because the pthread symbols are not in libpthread.a now. So this is different from PR 52590
The master branch has been updated by Alexandre Oliva <aoliva@gcc.gnu.org>: https://gcc.gnu.org/g:21edd841611a97442a6b95e8ec7e91ff8fd3a451 commit r13-6461-g21edd841611a97442a6b95e8ec7e91ff8fd3a451 Author: Alexandre Oliva <oliva@adacore.com> Date: Fri Mar 3 15:59:36 2023 -0300 link pthread_join from std::thread ctor Like pthread_create, pthread_join may fail to be statically linked in absent strong uses, so add to user code strong references to both when std::thread objects are created. for libstdc++-v3/ChangeLog PR libstdc++/104852 PR libstdc++/95989 PR libstdc++/52590 * include/bits/std_thread.h (thread::_M_thread_deps): New static implicitly-inline member function. (std::thread template ctor): Pass it to _M_start_thread. * src/c++11/thread.cc (thread::_M_start_thread): Name depend parameter, force it live on entry.
Should be fixed in the trunk (targeting 13). AFAIK it fails with 12 and 11. I know the patch works with 12, I've tested it there.