Bug 55394 - Using call_once without -lpthread compiles without warning
Summary: Using call_once without -lpthread compiles without warning
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.6.3
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 81517 (view as bug list)
Depends on: 84323
Blocks:
  Show dependency treegraph
 
Reported: 2012-11-19 12:28 UTC by Geert-Jan Giezeman
Modified: 2020-01-22 12:56 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-11-19 00:00:00


Attachments
Source file (167 bytes, text/x-c++src)
2012-11-19 12:28 UTC, Geert-Jan Giezeman
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Geert-Jan Giezeman 2012-11-19 12:28:43 UTC
Created attachment 28731 [details]
Source file

A source file which contains call_once will compile without any errors or warnings, even when libpthread is not linked. At run time, an exception will be thrown with a very unhelpful message. The attached source file demonstrates the problem.

$ g++ -Wall -Wextra -std=c++0x callonce.cpp
$ ./a.out
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)

Linking libpthread will remove the problem.

$ g++ -Wall -Wextra -std=c++0x callonce.cpp -lpthread
$ ./a.out
$ 

In the actual use case, call_once was called in a library that could be used in both multithreaded and singlethreaded code. That made it a hard to trace bug.

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
Comment 1 Jonathan Wakely 2012-11-19 13:44:48 UTC
(In reply to comment #0)
> A source file which contains call_once will compile without any errors or
> warnings, even when libpthread is not linked.

Obviously this is because compiling and linking are separate steps. The compiler front-end doesn't know in advance whether the linker will be invoked correctly.

It might be possible to do something similar to PR 52681 to improve the exception's message.
Comment 2 Paolo Carlini 2012-11-19 14:55:50 UTC
Library anyway.
Comment 3 Jonathan Wakely 2014-09-19 11:04:30 UTC
related to PR 58929
Comment 4 Markus Trippelsdorf 2016-11-19 09:04:25 UTC
clang's libc++.so.1 avoids the issue because it is linked with libpthread.so.0:

 % ldd /usr/lib/libc++.so.1
        linux-vdso.so.1 (0x00007ffc1618f000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007fe0f4fd7000)
        libc.so.6 => /lib/libc.so.6 (0x00007fe0f4c3a000)
        libm.so.6 => /lib/libm.so.6 (0x00007fe0f499f000)
        librt.so.1 => /lib/librt.so.1 (0x00007fe0f4797000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fe0f477e000)
        /lib64/ld-linux-x86-64.so.2 (0x00005575a195e000)

libstc++ isn't:

 % ldd /usr/lib/gcc/x86_64-pc-linux-gnu/7.0.0/libstdc++.so.6
        linux-vdso.so.1 (0x00007ffd14540000)
        libm.so.6 => /lib/libm.so.6 (0x00007f73bec87000)
        libc.so.6 => /lib/libc.so.6 (0x00007f73be8ea000)
        /lib64/ld-linux-x86-64.so.2 (0x00005594a5a06000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f73be8d1000)
Comment 5 Jonathan Wakely 2016-11-19 20:44:24 UTC
(In reply to Markus Trippelsdorf from comment #4)
> clang's libc++.so.1 avoids the issue because it is linked with
> libpthread.so.0:
> [...]
> libstc++ isn't:

Which is by design and a very important property to keep.

I was discussing a similar issue on IRC the other day and came to the conclusion that we should probably just call pthread_once() directly when the thread model is posix. Because that call is in a header not in libstdc++.so it won't make libstdc++.so depend on libpthread.so, but users that call std::call_once will depend on libpthread.so and users that don't call std::call_once won't depend on it. Which is what we want.
Comment 6 Jonathan Wakely 2017-07-22 20:48:38 UTC
*** Bug 81517 has been marked as a duplicate of this bug. ***
Comment 7 Andrea Bocci 2019-07-02 14:01:03 UTC
The same test program will fail in the same way, if compiled with -flto, even if -pthread is used:

$ g++-9 -Wall -Wextra -std=c++17 callonce.cpp -pthread
$ ./a.out

but

$ g++-9 -Wall -Wextra -std=c++17 callonce.cpp -pthread -flto
$ ./a.out 
terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)

Possibly because the LTO pass discards the dependency on libpthread.so:

$ ldd a.out 
        linux-vdso.so.1 (0x00007ffc09b46000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f420535e000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4204f7e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4205952000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f4204be0000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f42049c8000)
Comment 8 Tomasz Kłoczko 2020-01-22 12:56:43 UTC
Any progress on that issue?
Looks like I've hit this issu in protobuf https://github.com/protocolbuffers/protobuf/issues/7092