Created attachment 30398 [details] test case This bug goes back at least to 4.6, but I don't really care about anything older than 4.8. On x86_64-linux-gnu (and others), the attached test works when compiled with: g++ -std=c++0x -pthread std_mutex.cc -o std_mutex but when compiled with: g++ -std=c++0x -static -pthread std_mutex.cc -o std_mutex it either throws an error or just crashes. The underlying problem is excessive use of weak references in gthr-posix.h. I already have a fix and a testsuite addition in hand and will post them to gcc-patches soon.
I think it is bad form to use static linking with pthreads.
(In reply to Andrew Pinski from comment #1) > I think it is bad form to use static linking with pthreads. Nonsense. There is code specifically to ensure it works. The additions for C++11 thread interfaces just didn't do it right.
gthr-posix.h uses weakrefs and that is the right thing to do, the APIs are meant to be used regardless of whether libpthread has been linked in or not. The only reliable way to statically link libpthread.a from my experience is what we do in Fedora, i.e. ld -r the whole content of libpthread.a into libpthread.o and include that only in libpthread.a. While some libpthread.a objects have some dependencies, they have just a fraction of the needed ones.
weakrefs are right for the conditional cases. For the functions that underlie std::thread et al, it can never be meaningful to use those interfaces and fail to link with -lpthread. The Fedora hack just masks bugs like this one. It's not the right thing to do at all. The right thing is to fix the bugs. I have a fix, demonstrating it's certainly not impossible.
So my draft fix actually breaks the dynamic case. For the unconditional calls, weak is right in the shared library but strong is right in the static library. But unlike normal libraries, libstdc++ goes out of its way to get compiled only once, using PIC-compiled objects in the static library too. So there is no obvious way for gthr-posix.h to behave differently in the static and shared cases, which is the only correct thing for it to do.
Note also that libstdc++.a can be used together with libpthread.so or libstdc++.so with libpthread.a (g++ -static-libstdc++ etc.).
(In reply to Jakub Jelinek from comment #6) > Note also that libstdc++.a can be used together with libpthread.so or > libstdc++.so with libpthread.a (g++ -static-libstdc++ etc.). If libstdc++.a had strong references, it would work fine with libpthread.so too. That is the case that IMHO actually matters (-static-libstdc++ is important to avoid DSO dependencies specific to the GCC version, which varies across installations in incompatible ways far more than libc/libpthread versions). libstdc++.so's weak references can never work with libpthread.a unless there are other strong references elsewhere in the link. But I'm hard-pressed to think of a scenario in which someone actually wants libstdc++.so with libpthread.a.
(In reply to roland from comment #7) > -static-libstdc++ is important > to avoid DSO dependencies specific to the GCC version, which varies across > installations in incompatible ways far more than libc/libpthread versions). No it does not. Or rather there have not been an ABI change in libstdc++ since 3.4. If you compile with the oldest distro you support, it should work across all distros just fine. Just C++11 support was not part of most older distros because they came out before 2011 :).
(In reply to Andrew Pinski from comment #8) > (In reply to roland from comment #7) > > -static-libstdc++ is important > > to avoid DSO dependencies specific to the GCC version, which varies across > > installations in incompatible ways far more than libc/libpthread versions). > > No it does not. Or rather there have not been an ABI change in libstdc++ > since 3.4. If you compile with the oldest distro you support, it should > work across all distros just fine. Just C++11 support was not part of most > older distros because they came out before 2011 :). I think I've run into actual problems of this nature. Perhaps it was with 3.4 or earlier, or perhaps I'm misremembering. The only specific scenario I can recall at the moment might not have been a version skew issue, but rather the need to have libstdc++.so.N at runtime at all.
On Thu, 27 Jun 2013, pinskia at gcc dot gnu.org wrote: > No it does not. Or rather there have not been an ABI change in libstdc++ since > 3.4. If you compile with the oldest distro you support, it should work across > all distros just fine. Just C++11 support was not part of most older distros > because they came out before 2011 :). Compiling with a (newer) cross compiler built with a sysroot from the old distro has various advantages over actually trying to build directly on the old distro - but you do then need to use -static-libstdc++ -static-libgcc to avoid depending on newer shared libraries. (Actually, a sysroot just containing the old glibc libraries, with all other libraries linked in statically, seems to work better in my experience than a complete old-distro sysroot with old versions of lots of libraries; there are lots of ways an old library can cause problems for building new software where complete absence of that library is detected at configure time and doesn't cause problems.) In theory this (building widely portable binaries) is what LSB toolchains are for, but I don't think they are widely used.
Since r213922 pthread_create should get linked in, but apparently not pthread_join.
It's good to hear pthread_create should get linked in, but I also need pthread_join (and any other missing references) to get linked in before I can do anything useful with std::thread. I'm hoping this issue will keep getting some more love and attention. I'd be happy to do any testing for people if that's useful at all.
This is not really as gcc bug but rather not understanding weak symbols vs archives. Anyways this is a dup of bug 58909. *** This bug has been marked as a duplicate of bug 58909 ***