Summary: | Use of thread_local produces linking errors [now with gcc] | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Hannes Hauswedell <h2+fbsdports> | ||||
Component: | threads | Assignee: | freebsd-threads (Nobody) <threads> | ||||
Status: | Closed FIXED | ||||||
Severity: | Affects Some People | CC: | emaste, kib, tavianator | ||||
Priority: | --- | Keywords: | patch | ||||
Version: | 11.0-RELEASE | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
Hannes Hauswedell
2017-01-02 14:29:01 UTC
This is a bug in gcc. The libsupc++ configuration assumes that there are exactly two possibilities: either libc is glibc and implements __cxa_thread_atexit() using __cxa_thread_atexit_impl(), or libsupc++ must provide an implementation on its own. Right solution is to add detection of __cxa_thread_atexit() in libc, to libstdc++ configure.ac and libsupc++/atexit_thread.cc. A workaround for you is might be use of --allow-multiple-definition switch to ld. But what is not quite clear to me, is why libc __cxa_thread_atexit was searched for at all, since static linker should be satisfied with the first definition it found. Ensure that libstdc++.a appears strictly before libc.a on the linker invocation' command line. (In reply to Konstantin Belousov from comment #1) ok, I have opened an issue over at gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Let's see what they say. Concerning your proposed workaround: Since all the magic is done by cmake I have little influence on the order, although it does seem like it gets into libstdc++ first (see the "first defined here"). I have a different workaround in the code that I have also been using for FreeBSD<11 + LLVM and that I am now just expanding so that thread_local is just never used on FreeBSD right now. Upstream would be willing to create a workaround, however they are irritated with FreeBSD's solution and the workaround would of course only affect some future releases and not fix the current situation. Upstream suggested there is a better way to solving the whole __cxa_thread_atexit thing and/or that LLVM already has a (different) solution. Are there chances this will be changed, should I re-open https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192320 ? Thanks! Created attachment 178484 [details]
Provide __cxa_thread_atexit_impl(), split __cxa_thread_atexit() into separate .o.
This patch should help with gcc libstdc++ configured on stable/11 with __cxa_thread_atexit() already existing in libc. With the patch applied, gcc configure should detect __cxa_thread_atexit_impl() and generate only a wrapper cxa_thread_atexit() for libsupc++.
If gcc was configured on system where __cxa_thread_atexit(3) was not provided, but used on a system where it is, the patch does not make a difference.
Note that since https://reviews.llvm.org/D21803, upstream LLVM does basically the same thing as GCC. That is, it checks for __cxa_thread_atexit_impl in the libc, calling it if available, and emulating it if not. In either case, libc++abi unconditionally defines __cxa_thread_atexit. A commit references this bug: Author: kib Date: Sat Jan 7 16:05:19 UTC 2017 New revision: 311651 URL: https://svnweb.freebsd.org/changeset/base/311651 Log: Export __cxa_thread_atexit_impl as an alias for __cxa_thread_atexit. libstdc++ before gcc r244057 expected that libc provided __cxa_thread_atexit_impl, and libstdc++ implemented __cxa_thread_atexit, by forwarding the calls to _impl. Mentioned gcc revision checks for __cxa_thread_atexit in libc and does not provide the symbol from libstdc++ if found. This change helps older gcc, in particular, all released versions which implement thread_local, by consolidating the implementation into libc. For that versions, if configured with the current libc, the __cxa_thread_atexit is exported from libstdc++ as a trivial wrapper around libc::__cxa_thread_atexit_impl. The __cxa_thread_atexit implementation is put into separate source file to allow for static linking with older libstdc++.a. gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78968 Reported by: Hannes Hauswedell <h2+fbsdports@fsfe.org> PR: 215709 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Changes: head/lib/libc/include/libc_private.h head/lib/libc/stdlib/Makefile.inc head/lib/libc/stdlib/Symbol.map head/lib/libc/stdlib/cxa_thread_atexit.c head/lib/libc/stdlib/cxa_thread_atexit_impl.c Is this still waiting on MFC? |