This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: g++ -Wl,--as-needed -pthread behaviour
- From: Alan Modra <amodra at gmail dot com>
- To: Matthias Klose <doko at ubuntu dot com>
- Cc: gcc Development <gcc at gcc dot gnu dot org>, "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 24 Sep 2013 10:52:09 +0930
- Subject: Re: g++ -Wl,--as-needed -pthread behaviour
- Authentication-results: sourceware.org; auth=none
- References: <52402F23 dot 4030206 at ubuntu dot com>
On Mon, Sep 23, 2013 at 02:08:03PM +0200, Matthias Klose wrote:
> With binutils from the 2.24 branch or trunk, the behaviour of --as-needed did
> change, and what worked with binutils 2.23, now fails with 2.24:
>
> $ cat thread.cpp
> #include <thread>
>
> void factorial(int n, unsigned long long int *result) {
> if (n==1) {
> *result=1;
> return;
> }
> *result=1;
> for (; n!=0; n--) *result=*result*n;
> }
>
> int main() {
> unsigned long long int a;
> unsigned long long int *c=&a;
> std::thread t1(factorial,15,c);
> t1.join();
> return 0;
> }
> $ ld --version
> GNU ld (GNU Binutils for Ubuntu) 2.23.2
> $ g++ -Wl,--as-needed -pthread thread.cpp -std=c++11 -o thread && ./thread
>
> $ ld --version
> GNU ld (GNU Binutils for Debian) 2.23.52.20130828
> $ g++ -Wl,--as-needed -pthread thread.cpp -std=c++11 -o thread && ./thread
> terminate called after throwing an instance of 'std::system_error'
> what(): Enable multithreading to use std::thread: Operation not permitted
> Aborted
>
> So the test program doesn't have any direct references to symbols in libpthread,
> and isn't linked, and fails to run.
>
> According to the binutils maintainers, this behaviour is expected:
>
> https://sourceware.org/ml/binutils/2013-08/msg00286.html
> https://sourceware.org/ml/binutils/2013-09/msg00000.html
>
> but it seems a bit odd that g++ -Wl,--as-needed -pthread isn't working anymore.
Try compiling that testcase with -static rather than -Wl,--as-needed.
You'll hit std::system_error just like you do here. I believe that is
a libstdc++ bug, and can be solved by making libstdc++.a use strong
references to pthread symbols from std::thread::join() (and perhaps
other objects that provide c++ thread support, if there are such).
libstdc++.a objects that are just testing "is this program threaded"
should continue to use weak references.
Solving the problem with --as-needed and libstdc++.so isn't so easy.
One solution might be to split off thread support from libstdc++.so.6.
Otherwise we'd need to solve the transitive reference somehow.
ie. Teach the linker that a reference to std::thread::join() means
that pthread_create is required. One obvious way to do that is have
the compiler reference pthread_create in objects that use
std::thread::join().
--
Alan Modra
Australia Development Lab, IBM