Bug 57740 - C++11 std::thread not usable with static linking
Summary: C++11 std::thread not usable with static linking
Status: RESOLVED DUPLICATE of bug 58909
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-27 20:18 UTC by roland
Modified: 2016-08-14 16:05 UTC (History)
1 user (show)

See Also:
Host: x86_64-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
test case (377 bytes, text/plain)
2013-06-27 20:18 UTC, roland
Details

Note You need to log in before you can comment on or make changes to this bug.
Description roland 2013-06-27 20:18:42 UTC
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.
Comment 1 Andrew Pinski 2013-06-27 20:20:03 UTC
I think it is bad form to use static linking with pthreads.
Comment 2 roland 2013-06-27 20:29:58 UTC
(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.
Comment 3 Jakub Jelinek 2013-06-27 20:44:45 UTC
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.
Comment 4 roland 2013-06-27 20:57:11 UTC
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.
Comment 5 roland 2013-06-27 21:09:13 UTC
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.
Comment 6 Jakub Jelinek 2013-06-27 21:15:19 UTC
Note also that libstdc++.a can be used together with libpthread.so or libstdc++.so with libpthread.a (g++ -static-libstdc++ etc.).
Comment 7 roland 2013-06-27 21:24:57 UTC
(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.
Comment 8 Andrew Pinski 2013-06-27 21:51:19 UTC
(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 :).
Comment 9 roland 2013-06-27 22:12:47 UTC
(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.
Comment 10 jsm-csl@polyomino.org.uk 2013-06-27 23:20:16 UTC
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.
Comment 11 Jonathan Wakely 2014-10-13 14:56:51 UTC
Since r213922 pthread_create should get linked in, but apparently not pthread_join.
Comment 12 Michael 2014-11-04 03:32:39 UTC
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.
Comment 13 Andrew Pinski 2016-08-14 16:05:59 UTC
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 ***